From 3c45518d1fd9837d740821c825dd9cc5744e9dd8 Mon Sep 17 00:00:00 2001 From: Beatriz Mira Mendes Date: Tue, 2 Apr 2024 12:03:19 +0100 Subject: [PATCH] [android] Fix: Display list of stop points in ruler and transit mode properly in RTL Changes made: - In MultilineLayoutManager.java: if called with LAYOUT_DIRECTION_RTL tag, the layout is now properly written. - In RoutinBottomMenuController.java: MultilineLayoutManager class is now called with the new parameter, the mTransitFrame's layout direction. - In DotDividerItemDecoration.java: to properly place the dots between the elements in the list, these elements are iterated from right to left when the layout direction is RTL. Signed-off-by: Beatriz Mira Mendes --- .../routing/RoutingBottomMenuController.java | 4 ++-- .../recycler/DotDividerItemDecoration.java | 6 ++++-- .../widget/recycler/MultilineLayoutManager.java | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java index d2ff7ab2b1..748cb17855 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java @@ -176,7 +176,7 @@ final class RoutingBottomMenuController implements View.OnClickListener UiUtils.show(mTransitFrame); RecyclerView rv = mTransitFrame.findViewById(R.id.transit_recycler_view); TransitStepAdapter adapter = new TransitStepAdapter(); - rv.setLayoutManager(new MultilineLayoutManager()); + rv.setLayoutManager(new MultilineLayoutManager(mTransitFrame.getLayoutDirection())); rv.setNestedScrollingEnabled(false); rv.removeItemDecoration(mTransitViewDecorator); rv.addItemDecoration(mTransitViewDecorator); @@ -206,7 +206,7 @@ final class RoutingBottomMenuController implements View.OnClickListener { UiUtils.show(rv); final TransitStepAdapter adapter = new TransitStepAdapter(); - rv.setLayoutManager(new MultilineLayoutManager()); + rv.setLayoutManager(new MultilineLayoutManager(mTransitFrame.getLayoutDirection())); rv.setNestedScrollingEnabled(false); rv.removeItemDecoration(mTransitViewDecorator); rv.addItemDecoration(mTransitViewDecorator); diff --git a/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java b/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java index 77b5964f77..d3fff7b4d8 100644 --- a/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java +++ b/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java @@ -41,7 +41,10 @@ public class DotDividerItemDecoration extends RecyclerView.ItemDecoration return; int childCount = parent.getChildCount(); - for (int i = 0; i < childCount - 1; i++) + boolean parentLayoutRTL = (parent.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); + + for (int i = parentLayoutRTL ? childCount - 1 : 0; parentLayoutRTL ? i > 0 : i < childCount - 1; + i += parentLayoutRTL ? -1 : 1) { View child = parent.getChildAt(i); @@ -53,7 +56,6 @@ public class DotDividerItemDecoration extends RecyclerView.ItemDecoration int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); - mDivider.draw(c); } } diff --git a/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java b/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java index 0c3c9ed105..84326e1068 100644 --- a/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java +++ b/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java @@ -8,9 +8,12 @@ import androidx.recyclerview.widget.RecyclerView; public class MultilineLayoutManager extends RecyclerView.LayoutManager { - public MultilineLayoutManager() + private boolean reverseLayout = false; + + public MultilineLayoutManager(int layoutDirection) { setAutoMeasureEnabled(true); + reverseLayout = layoutDirection == View.LAYOUT_DIRECTION_RTL; } @Override @@ -25,6 +28,8 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager { detachAndScrapAttachedViews(recycler); + assertInLayoutOrScroll(null); + int widthUsed = 0; int heightUsed = 0; int lineHeight = 0; @@ -55,7 +60,11 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager } lineHeight = 0; } - layoutDecorated(child, widthUsed, heightUsed, widthUsed + width, heightUsed + height); + if (reverseLayout) + layoutDecoratedWithMargins(child, getWidth() - widthUsed - width, heightUsed, + getWidth() - widthUsed, heightUsed + height); + else + layoutDecorated(child, widthUsed, heightUsed, widthUsed + width, heightUsed + height); widthUsed += width; itemsCountOneLine++; } @@ -63,7 +72,7 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager private int squeezeChildIntoLine(int widthUsed, int heightUsed, @NonNull View child) { - if (!(child instanceof SqueezingInterface)) + if (!(child instanceof SqueezingInterface)) return getDecoratedMeasuredWidth(child); int availableWidth = getWidth() - widthUsed - getDecoratedRight(child); @@ -79,6 +88,7 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager public interface SqueezingInterface { void squeezeTo(@Dimension int width); + @Dimension int getMinimumAcceptableSize(); }