[Huawei Developers] Sherlock F:
Direction Steps

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/002/250/698/2640091000002250698.20201014132033.21894301466783200793770755955368:50511027012327:2800:9E7C75D935BA5C73CA724BDCE6F743CEFE0804DEFB38D1B0AF567B767ADF5102.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/002/250/698/2640091000002250698.20201014132033.21894301466783200793770755955368:50511027012327:2800:9E7C75D935BA5C73CA724BDCE6F743CEFE0804DEFB38D1B0AF567B767ADF5102.gif[/IMG]

Overview

This article will guide to view the Directions steps for all types such as driving, by-cycling and walking.

In this, Used BottomSheet Layout for better user experience. For using BottomSheet, need to set app:layout_behavior attribute to NestedScrollView. Check the below code

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">

<androidx.core.widget.NestedScrollView
android:id="@+id/bottom_sheet_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<View
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/tool_gradient" />

<include layout="@layout/content_steps" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Check the below code for tool_gradient.xml drawable

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:startColor="#fff" />
</shape>

Check the below code for content_steps.xml layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:orientation="vertical">

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dimen_10">

<ImageView
android:id="@+id/img_time"
android:layout_width="@dimen/dimen_30"
android:layout_height="@dimen/dimen_30"
android:src="@drawable/time_pc" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_toEndOf="@id/img_time"
android:text="Distance"
android:textColor="#000"
android:textSize="14sp" />
</RelativeLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dimen_10"
android:layout_marginTop="@dimen/dimen_10"
android:orientation="horizontal">

<TextView
android:id="@+id/txt_distance_steps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="15.34"
android:textColor="@color/red"
android:textSize="25sp"
android:textStyle="bold" />

<TextView
android:id="@+id/txtMKM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" km" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<ImageView
android:layout_width="@dimen/dimen_10"
android:layout_height="@dimen/dimen_10"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/dimen_30"
android:src="@drawable/circular_marker" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_50"
android:text="Your Location"
android:textColor="#000"
android:textSize="14sp" />
</LinearLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dimen_10"
android:layout_marginTop="@dimen/dimen_10" />

</LinearLayout>

After that, Add below code in Activity onCreate. Here bottomSheetStepsView is View object and behaviourSteps is BottomSheetBehavior object

bottomSheetStepsView = findViewById(R.id.bottom_sheet_steps);
behaviourSteps = BottomSheetBehavior.from(bottomSheetStepsView);
behaviourSteps.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@SuppressLint("RestrictedApi")
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_EXPANDED:
myLocationFab.setVisibility(View.INVISIBLE);
imgBackDirections.setVisibility(View.INVISIBLE);
txtDirectionAddress.setVisibility(View.VISIBLE);
break;
case BottomSheetBehavior.STATE_DRAGGING:
myLocationFab.setVisibility(View.INVISIBLE);
break;
case BottomSheetBehavior.STATE_COLLAPSED:
myLocationFab.setVisibility(View.VISIBLE);
imgBackDirections.setVisibility(View.VISIBLE);
txtDirectionAddress.setVisibility(View.INVISIBLE);
behaviourSteps.setPeekHeight(900);
break;
}
}

@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// React to dragging events
}
});

Initialize steps adapter

private void initStepsAdapter() {
stepsAdapter = new StepsAdapter(this);
stepsAdapter.type = 0;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerViewSteps.setLayoutManager(linearLayoutManager);
recyclerViewSteps.setItemAnimator(new DefaultItemAnimator());
recyclerViewSteps.setAdapter(stepsAdapter);
}

In the Direction API response we will get steps response. Here directionType will be driving,bycycling or walking based on requirements. Check the below code

private void callDirectionsApi(final String directionType) {
if (!NetworkUtil.isNetworkConnected(this)) {
showNetworkDialog();
return;
}
Origin origin = new Origin();
origin.setLat(myLocation.getLatitude());
origin.setLng(myLocation.getLongitude());
Destination destination = new Destination();
destination.setLat(destinationLocation.getLat());
destination.setLng(destinationLocation.getLng());
DirectionsRequest request = new DirectionsRequest();
request.setOrigin(origin);
request.setDestination(destination);
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<DirectionsResponse> call = apiInterface.getDirections(directionType, request);
call.enqueue(new Callback<DirectionsResponse>() {
@Override
public void onResponse(@NotNull Call<DirectionsResponse> call, @NotNull Response<DirectionsResponse> response) {
if (response.isSuccessful()) {
DirectionsResponse directionsResponse = response.body();
assert directionsResponse != null;
Log.e(TAG + " Response", directionsResponse.toString());
List<RoutesItem> routesItemList = directionsResponse.getRoutes();
if (routesItemList.size() > 0) {
PathsItem pathsItem = (routesItemList.get(0).getPaths().get(0));
String distance, mORkm;
if (pathsItem.getDistance() < 1000) {
distance = String.valueOf((int) pathsItem.getDistance());
mORkm = " m";
} else {
distance = String.valueOf((int) pathsItem.getDistance() / 1000);
mORkm = " km";
}
txtMKMSteps.setText(mORkm);
txtDirectionTitle.setText(destinationName);
txtDistanceSteps.setText(distance);
txtDirectionAddress.setText(pathsItem.getEndAddress());
List<StepsItem> steps = routesItemList.get(0).getPaths().get(0).getSteps();
setStepsData(steps);
}

@Override
public void onFailure
(@NotNull Call<DirectionsResponse> call, @NotNull Throwable t) {
Log.e(TAG + " Response Error", Objects.requireNonNull(t.getMessage()));
}
});
}

Add the steps data to Steps Adapter

private void setStepsData(List<StepsItem> steps) {
stepsAdapter.addList(steps);
}

Steps item layout for adapter. Check the below code

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lout_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<ImageView
android:id="@+id/img_step_direction"
android:layout_width="@dimen/dimen_50"
android:layout_height="@dimen/dimen_50"
android:layout_gravity="center"
android:layout_margin="@dimen/dimen_10"
android:padding="7dp"
android:src="@drawable/turn_left" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_10"
android:layout_marginTop="@dimen/dimen_10"
android:layout_marginEnd="@dimen/dimen_10"
android:orientation="vertical">

<TextView
android:id="@+id/txt_distance_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.1 km"
android:textSize="14sp" />

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">

<TextView
android:id="@+id/txt_step_instruction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Turn left and take Renigunta Road"
android:textColor="#000"
android:textSize="14sp" />

<TextView
android:id="@+id/txt_road_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/txt_step_instruction"
android:text="Renigunta Road"
android:layout_marginBottom="@dimen/dimen_10"
android:textSize="14sp" />
</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/txt_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2 min"
android:textColor="#000"
android:textSize="14sp" />

<TextView
android:id="@+id/txt_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_30"
android:layout_toEndOf="@id/txt_time"
android:text="1.1 km"
android:textColor="#000"
android:textSize="14sp" />

<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="0.1dp"
android:layout_marginStart="@dimen/dimen_20"
android:layout_marginTop="@dimen/dimen_15"
android:layout_marginEnd="@dimen/dimen_20"
android:layout_toEndOf="@id/txt_distance"
android:background="@color/grey" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>

Check the below code for StepsAdapter

public class StepsAdapter extends RecyclerView.Adapter<StepsAdapter.MyHolder> {
private ArrayList<StepsItem> list = new ArrayList<>();
private Context context;
public int type = 0;

public void addList(List<StepsItem> stepsList) {
if (list != null) {
list.clear();
list.addAll(stepsList);
notifyDataSetChanged();
}
}

StepsAdapter(Context context) {
this.context = context;
}

public class MyHolder extends RecyclerView.ViewHolder {
LinearLayout loutRoot;
TextView txtInstruction, txtRoadName;
ImageView imgStepDirection;
TextView txtTime, txtDistance;
TextView txtDistanceTop;
View view;

public MyHolder(@NonNull View itemView) {
super(itemView);
txtInstruction = itemView.findViewById(R.id.txt_step_instruction);
txtRoadName = itemView.findViewById(R.id.txt_road_name);
imgStepDirection = itemView.findViewById(R.id.img_step_direction);
txtTime = itemView.findViewById(R.id.txt_time);
txtDistance = itemView.findViewById(R.id.txt_distance);
txtDistanceTop = itemView.findViewById(R.id.txt_distance_top);
view = itemView.findViewById(R.id.view);
loutRoot = itemView.findViewById(R.id.lout_root);
}
}

@NonNull
@Override
public StepsAdapter.MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflate_steps_item, parent, false);
return new StepsAdapter.MyHolder(view);
}

@Override
public void onBindViewHolder(@NonNull final StepsAdapter.MyHolder holder, final int position) {
if (type == 0) {
holder.txtDistanceTop.setVisibility(View.GONE);
} else {
holder.txtDistance.setVisibility(View.GONE);
holder.txtTime.setVisibility(View.GONE);
holder.view.setVisibility(View.GONE);
}
holder.txtInstruction.setText(list.get(position).getInstruction());
holder.txtDistance.setText(list.get(position).getDistanceText());
holder.txtDistanceTop.setText(list.get(position).getDistanceText());
holder.txtTime.setText(list.get(position).getDurationText());
holder.txtRoadName.setText(list.get(position).getRoadName());
int imageResource;
if (list.get(position).getAction().contains("left")) {
imageResource = R.drawable.turn_left;
} else if (list.get(position).getAction().contains("right")) {
imageResource = R.drawable.turn_right;
} else if (list.get(position).getAction().contains("straight")) {
imageResource = R.drawable.straight;
} else {
imageResource = 0;
}
Glide.with(context).load(imageResource).into(holder.imgStepDirection);
holder.loutRoot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StepsAdapter.MapStepClick placeClick = (StepsAdapter.MapStepClick) context;
placeClick.mapStepClick(list, position);
}
});
}

@Override
public int getItemCount() {
return list.size();
}

interface MapStepClick {
void mapStepClick(ArrayList<StepsItem> list, int position);
}
}

Find the output in below image

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/002/250/698/2640091000002250698.20201014141242.15106107878596599372015202536519:50511027014415:2800:C6E59EC79F5CF4522D44BB6A3136F13619BCA223466498B84B1C393155642A17.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/002/250/698/2640091000002250698.20201014141242.15106107878596599372015202536519:50511027014415:2800:C6E59EC79F5CF4522D44BB6A3136F13619BCA223466498B84B1C393155642A17.jpg[/IMG]

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/002/250/698/2640091000002250698.20201014141246.71763785065452267033967637935720:50511027014415:2800:47D8F7EF379E05CFEA3BA1ECBB24E11677353A9B3441B9B5D3008DB1CB70EFFD.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/002/250/698/2640091000002250698.20201014141246.71763785065452267033967637935720:50511027014415:2800:47D8F7EF379E05CFEA3BA1ECBB24E11677353A9B3441B9B5D3008DB1CB70EFFD.jpg[/IMG]

Conclusion

In this article we can learn about Direction Steps and BottomSheet Behaviour and it's callbacks. Based on these steps data we can develop preview routes.

Let’s wait for next article.

More information, you can visit https://forums.developer.huawei.com/forumPortal/en/home?tagId=0801188417594370004