diff --git a/android/res/layout/layout_nav_top.xml b/android/res/layout/layout_nav_top.xml
index 88759a3cf1..08519e5817 100644
--- a/android/res/layout/layout_nav_top.xml
+++ b/android/res/layout/layout_nav_top.xml
@@ -104,4 +104,15 @@
tools:src="@drawable/ic_then_left_sharp"/>
+
+
+
+
+
\ No newline at end of file
diff --git a/android/res/layout/nav_lanes.xml b/android/res/layout/nav_lanes.xml
new file mode 100644
index 0000000000..9db6f67607
--- /dev/null
+++ b/android/res/layout/nav_lanes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/android/res/layout/nav_single_lane.xml b/android/res/layout/nav_single_lane.xml
new file mode 100644
index 0000000000..02943a6ad6
--- /dev/null
+++ b/android/res/layout/nav_single_lane.xml
@@ -0,0 +1,12 @@
+
+
diff --git a/android/res/values/dimens.xml b/android/res/values/dimens.xml
index cb2367285b..e408417873 100644
--- a/android/res/values/dimens.xml
+++ b/android/res/values/dimens.xml
@@ -114,6 +114,7 @@
70sp
64dp
360dp
+ 48dp
@dimen/margin_half
64dp
diff --git a/android/res/values/themes-attrs.xml b/android/res/values/themes-attrs.xml
index 3e82d4eb99..c7dd7377c5 100644
--- a/android/res/values/themes-attrs.xml
+++ b/android/res/values/themes-attrs.xml
@@ -19,6 +19,7 @@
+
diff --git a/android/res/values/themes-base.xml b/android/res/values/themes-base.xml
index 7c6d4866fa..7ba5288e45 100644
--- a/android/res/values/themes-base.xml
+++ b/android/res/values/themes-base.xml
@@ -45,6 +45,7 @@
- @drawable/bg_nav_next_turn
- @drawable/bg_nav_next_next_turn
+ - @color/base_accent
- @drawable/button
- @color/button_text
@@ -179,6 +180,7 @@
- @drawable/bg_nav_next_turn_night
- @drawable/bg_nav_next_next_turn_night
+ - @color/base_accent_night
- @drawable/button_night
- @color/button_text_night
diff --git a/android/src/app/organicmaps/routing/LanesAdapter.java b/android/src/app/organicmaps/routing/LanesAdapter.java
new file mode 100644
index 0000000000..eb02b47760
--- /dev/null
+++ b/android/src/app/organicmaps/routing/LanesAdapter.java
@@ -0,0 +1,71 @@
+package app.organicmaps.routing;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import app.organicmaps.R;
+import app.organicmaps.widget.ArrowView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LanesAdapter extends RecyclerView.Adapter
+{
+ @NonNull
+ private final List mItems = new ArrayList<>();
+
+ @NonNull
+ @Override
+ public LanesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
+ {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ final View root = inflater.inflate(R.layout.nav_single_lane, parent, false);
+ return new LanesViewHolder(root);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull LanesViewHolder holder, int position)
+ {
+ holder.bind(mItems.get(position));
+ }
+
+ @Override
+ public int getItemCount()
+ {
+ return mItems.size();
+ }
+
+ public void setItems(@NonNull List items)
+ {
+ mItems.clear();
+ mItems.addAll(items);
+ notifyDataSetChanged();
+ }
+
+ public void clearItems()
+ {
+ boolean alreadyEmpty = mItems.isEmpty();
+ mItems.clear();
+ if (!alreadyEmpty)
+ notifyDataSetChanged();
+ }
+
+ static class LanesViewHolder extends RecyclerView.ViewHolder
+ {
+ @NonNull
+ private final ArrowView mArrow;
+
+ public LanesViewHolder(@NonNull View itemView)
+ {
+ super(itemView);
+ mArrow = itemView.findViewById(R.id.lane_image);
+ }
+
+ void bind(@NonNull SingleLaneInfo info)
+ {
+ }
+ }
+}
diff --git a/android/src/app/organicmaps/routing/NavigationController.java b/android/src/app/organicmaps/routing/NavigationController.java
index 36a3eb887a..2110c9bbea 100644
--- a/android/src/app/organicmaps/routing/NavigationController.java
+++ b/android/src/app/organicmaps/routing/NavigationController.java
@@ -20,6 +20,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
+import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import app.organicmaps.Framework;
import app.organicmaps.MwmActivity;
@@ -32,6 +33,8 @@ import app.organicmaps.widget.menu.NavMenu;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
+import java.util.Arrays;
+
public class NavigationController implements Application.ActivityLifecycleCallbacks,
TrafficManager.TrafficCallback,
NavMenu.NavMenuListener
@@ -50,6 +53,11 @@ public class NavigationController implements Application.ActivityLifecycleCallba
private final View mStreetFrame;
private final TextView mNextStreet;
+ @NonNull
+ private final RecyclerView mLanes;
+ @NonNull
+ private final LanesAdapter mLanesAdapter;
+
@NonNull
private final MapButtonsController mMapButtonsController;
@@ -90,6 +98,12 @@ public class NavigationController implements Application.ActivityLifecycleCallba
});
}
+ private void initLanesRecycler()
+ {
+ mLanes.setAdapter(mLanesAdapter);
+ mLanes.setNestedScrollingEnabled(false);
+ }
+
public NavigationController(AppCompatActivity activity, @NonNull MapButtonsController mapButtonsController, View.OnClickListener onSettingsClickListener)
{
mFrame = activity.findViewById(R.id.navigation_frame);
@@ -112,6 +126,10 @@ public class NavigationController implements Application.ActivityLifecycleCallba
mStreetFrame = topFrame.findViewById(R.id.street_frame);
mNextStreet = mStreetFrame.findViewById(R.id.street);
+ mLanes = topFrame.findViewById(R.id.lanes);
+ mLanesAdapter = new LanesAdapter();
+ initLanesRecycler();
+
// Show a blank view below the navbar to hide the menu content
final View navigationBarBackground = mFrame.findViewById(R.id.nav_bottom_sheet_nav_bar);
final View nextTurnContainer = mFrame.findViewById(R.id.nav_next_turn_container);
@@ -185,6 +203,11 @@ public class NavigationController implements Application.ActivityLifecycleCallba
UiUtils.showIf(info.nextCarDirection.containsNextTurn(), mNextNextTurnFrame);
if (info.nextCarDirection.containsNextTurn())
info.nextCarDirection.setNextTurnDrawable(mNextNextTurnImage);
+
+ if (info.lanes != null)
+ mLanesAdapter.setItems(Arrays.asList(info.lanes));
+ else
+ mLanesAdapter.clearItems();
}
private void updatePedestrian(RoutingInfo info)