From decfaa0d3eede896a2e13567d239d193722f9a54 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Tue, 12 Jul 2022 19:27:36 +0200 Subject: [PATCH] [android] use separate buttons layout for each map mode A layout for regular, planning and navigation map modes Signed-off-by: Arnaud Vergnet --- ....xml => map_buttons_layout_navigation.xml} | 60 ++-- .../map_buttons_layout_planning.xml | 63 ++++ .../map_buttons_layout_regular.xml | 95 ++++++ ...frame.xml => map_buttons_search_frame.xml} | 0 android/res/layout/activity_map.xml | 6 +- ...ookmarks.xml => map_buttons_bookmarks.xml} | 0 android/res/layout/map_buttons_help.xml | 6 + ...tons_layers.xml => map_buttons_layers.xml} | 0 ....xml => map_buttons_layout_navigation.xml} | 60 ++-- .../layout/map_buttons_layout_planning.xml | 61 ++++ .../res/layout/map_buttons_layout_regular.xml | 93 ++++++ ..._buttons_menu.xml => map_buttons_menu.xml} | 0 ...osition.xml => map_buttons_myposition.xml} | 0 ...tons_search.xml => map_buttons_search.xml} | 0 ...frame.xml => map_buttons_search_frame.xml} | 0 ..._buttons_zoom.xml => map_buttons_zoom.xml} | 0 android/res/values-land/dimens.xml | 2 + android/res/values-w320dp/dimens.xml | 4 - android/res/values-w360dp/dimens.xml | 4 - android/res/values/dimens.xml | 2 +- .../src/com/mapswithme/maps/MapFragment.java | 4 +- .../src/com/mapswithme/maps/MwmActivity.java | 81 +++-- .../maps/maplayer/MapButtonsController.java | 305 ++++++++++++------ .../maps/maplayer/MapLayersController.java | 6 +- .../mapswithme/maps/maplayer/SearchWheel.java | 108 ++++--- .../maps/routing/RoutingController.java | 47 ++- .../mapswithme/maps/widget/menu/MainMenu.java | 18 +- .../maps/widget/menu/MyPositionButton.java | 3 +- 28 files changed, 749 insertions(+), 279 deletions(-) rename android/res/layout-land/{map_navigation_buttons.xml => map_buttons_layout_navigation.xml} (64%) create mode 100644 android/res/layout-land/map_buttons_layout_planning.xml create mode 100644 android/res/layout-land/map_buttons_layout_regular.xml rename android/res/layout-land/{map_navigation_buttons_search_frame.xml => map_buttons_search_frame.xml} (100%) rename android/res/layout/{map_navigation_buttons_bookmarks.xml => map_buttons_bookmarks.xml} (100%) create mode 100644 android/res/layout/map_buttons_help.xml rename android/res/layout/{map_navigation_buttons_layers.xml => map_buttons_layers.xml} (100%) rename android/res/layout/{map_navigation_buttons.xml => map_buttons_layout_navigation.xml} (64%) create mode 100644 android/res/layout/map_buttons_layout_planning.xml create mode 100644 android/res/layout/map_buttons_layout_regular.xml rename android/res/layout/{map_navigation_buttons_menu.xml => map_buttons_menu.xml} (100%) rename android/res/layout/{map_navigation_buttons_myposition.xml => map_buttons_myposition.xml} (100%) rename android/res/layout/{map_navigation_buttons_search.xml => map_buttons_search.xml} (100%) rename android/res/layout/{map_navigation_buttons_search_frame.xml => map_buttons_search_frame.xml} (100%) rename android/res/layout/{map_navigation_buttons_zoom.xml => map_buttons_zoom.xml} (100%) delete mode 100644 android/res/values-w320dp/dimens.xml delete mode 100644 android/res/values-w360dp/dimens.xml diff --git a/android/res/layout-land/map_navigation_buttons.xml b/android/res/layout-land/map_buttons_layout_navigation.xml similarity index 64% rename from android/res/layout-land/map_navigation_buttons.xml rename to android/res/layout-land/map_buttons_layout_navigation.xml index 93366d046e..c0e4253148 100644 --- a/android/res/layout-land/map_navigation_buttons.xml +++ b/android/res/layout-land/map_buttons_layout_navigation.xml @@ -1,9 +1,8 @@ - @@ -14,26 +13,26 @@ android:visibility="gone" tools:visibility="visible" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent"> - + app:layout_constraintBottom_toTopOf="@+id/btn_bookmarks" + app:layout_constraintStart_toStartOf="parent" /> + + - - \ No newline at end of file + \ No newline at end of file diff --git a/android/res/layout-land/map_buttons_layout_planning.xml b/android/res/layout-land/map_buttons_layout_planning.xml new file mode 100644 index 0000000000..0f53774e9d --- /dev/null +++ b/android/res/layout-land/map_buttons_layout_planning.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/res/layout-land/map_buttons_layout_regular.xml b/android/res/layout-land/map_buttons_layout_regular.xml new file mode 100644 index 0000000000..cff7fda11c --- /dev/null +++ b/android/res/layout-land/map_buttons_layout_regular.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/res/layout-land/map_navigation_buttons_search_frame.xml b/android/res/layout-land/map_buttons_search_frame.xml similarity index 100% rename from android/res/layout-land/map_navigation_buttons_search_frame.xml rename to android/res/layout-land/map_buttons_search_frame.xml diff --git a/android/res/layout/activity_map.xml b/android/res/layout/activity_map.xml index 4c60c4810a..97272fc800 100644 --- a/android/res/layout/activity_map.xml +++ b/android/res/layout/activity_map.xml @@ -25,8 +25,10 @@ android:id="@+id/position_chooser" layout="@layout/position_chooser"/> - + + \ No newline at end of file diff --git a/android/res/layout/map_navigation_buttons_layers.xml b/android/res/layout/map_buttons_layers.xml similarity index 100% rename from android/res/layout/map_navigation_buttons_layers.xml rename to android/res/layout/map_buttons_layers.xml diff --git a/android/res/layout/map_navigation_buttons.xml b/android/res/layout/map_buttons_layout_navigation.xml similarity index 64% rename from android/res/layout/map_navigation_buttons.xml rename to android/res/layout/map_buttons_layout_navigation.xml index 566dbfb792..9f8fa08d9f 100644 --- a/android/res/layout/map_navigation_buttons.xml +++ b/android/res/layout/map_buttons_layout_navigation.xml @@ -1,9 +1,8 @@ - @@ -14,26 +13,26 @@ android:visibility="gone" tools:visibility="visible" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent"> - + app:layout_constraintBottom_toTopOf="@+id/btn_bookmarks" + app:layout_constraintStart_toStartOf="parent" /> + + - - \ No newline at end of file + \ No newline at end of file diff --git a/android/res/layout/map_buttons_layout_planning.xml b/android/res/layout/map_buttons_layout_planning.xml new file mode 100644 index 0000000000..0ffdd6fadf --- /dev/null +++ b/android/res/layout/map_buttons_layout_planning.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/res/layout/map_buttons_layout_regular.xml b/android/res/layout/map_buttons_layout_regular.xml new file mode 100644 index 0000000000..ab7b0a29b9 --- /dev/null +++ b/android/res/layout/map_buttons_layout_regular.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/res/layout/map_navigation_buttons_menu.xml b/android/res/layout/map_buttons_menu.xml similarity index 100% rename from android/res/layout/map_navigation_buttons_menu.xml rename to android/res/layout/map_buttons_menu.xml diff --git a/android/res/layout/map_navigation_buttons_myposition.xml b/android/res/layout/map_buttons_myposition.xml similarity index 100% rename from android/res/layout/map_navigation_buttons_myposition.xml rename to android/res/layout/map_buttons_myposition.xml diff --git a/android/res/layout/map_navigation_buttons_search.xml b/android/res/layout/map_buttons_search.xml similarity index 100% rename from android/res/layout/map_navigation_buttons_search.xml rename to android/res/layout/map_buttons_search.xml diff --git a/android/res/layout/map_navigation_buttons_search_frame.xml b/android/res/layout/map_buttons_search_frame.xml similarity index 100% rename from android/res/layout/map_navigation_buttons_search_frame.xml rename to android/res/layout/map_buttons_search_frame.xml diff --git a/android/res/layout/map_navigation_buttons_zoom.xml b/android/res/layout/map_buttons_zoom.xml similarity index 100% rename from android/res/layout/map_navigation_buttons_zoom.xml rename to android/res/layout/map_buttons_zoom.xml diff --git a/android/res/values-land/dimens.xml b/android/res/values-land/dimens.xml index 5b91c29412..c5c87d2b01 100644 --- a/android/res/values-land/dimens.xml +++ b/android/res/values-land/dimens.xml @@ -6,6 +6,8 @@ 72dp 88dp + 100dp + 48dp 16dp diff --git a/android/res/values-w320dp/dimens.xml b/android/res/values-w320dp/dimens.xml deleted file mode 100644 index aaec11b224..0000000000 --- a/android/res/values-w320dp/dimens.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - 136dp - diff --git a/android/res/values-w360dp/dimens.xml b/android/res/values-w360dp/dimens.xml deleted file mode 100644 index aaec11b224..0000000000 --- a/android/res/values-w360dp/dimens.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - 136dp - diff --git a/android/res/values/dimens.xml b/android/res/values/dimens.xml index 3b42e73549..d6eca6cb95 100644 --- a/android/res/values/dimens.xml +++ b/android/res/values/dimens.xml @@ -138,7 +138,7 @@ 360dp @dimen/margin_half - 136dp + 136dp 12dp 4dp diff --git a/android/src/com/mapswithme/maps/MapFragment.java b/android/src/com/mapswithme/maps/MapFragment.java index 1bd5235ea3..a7f51bce9f 100644 --- a/android/src/com/mapswithme/maps/MapFragment.java +++ b/android/src/com/mapswithme/maps/MapFragment.java @@ -59,6 +59,7 @@ public class MapFragment extends BaseMwmFragment private int mHeight; private int mWidth; + private int mBottomWidgetOffset; private boolean mRequireResize; private boolean mSurfaceCreated; private boolean mSurfaceAttached; @@ -78,7 +79,7 @@ public class MapFragment extends BaseMwmFragment Context context = requireContext(); nativeCleanWidgets(); - setupBottomWidgetsOffset(0); + setupBottomWidgetsOffset(mBottomWidgetOffset); nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, UiUtils.dimen(context, R.dimen.margin_base), @@ -104,6 +105,7 @@ public class MapFragment extends BaseMwmFragment void setupBottomWidgetsOffset(int offset) { + mBottomWidgetOffset = offset; setupRuler(offset, true); setupAttribution(offset, true); } diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 18e2a8f98b..f439c82802 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -28,6 +28,7 @@ import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; import com.mapswithme.maps.Framework.PlacePageActivationListener; import com.mapswithme.maps.api.Const; import com.mapswithme.maps.background.AppBackgroundTracker; @@ -129,6 +130,7 @@ public class MwmActivity extends BaseMwmFragmentActivity ReportFragment.class.getName() }; private static final String EXTRA_LOCATION_DIALOG_IS_ANNOYING = "LOCATION_DIALOG_IS_ANNOYING"; + private static final String EXTRA_CURRENT_LAYOUT_MODE = "CURRENT_LAYOUT_MODE"; private static final int REQ_CODE_LOCATION_PERMISSION = 1; private static final int REQ_CODE_LOCATION_PERMISSION_ON_CLICK = 2; public static final int REQ_CODE_ERROR_DRIVING_OPTIONS_DIALOG = 5; @@ -169,7 +171,7 @@ public class MwmActivity extends BaseMwmFragmentActivity @NonNull private MenuBottomSheetFragment mMainMenuBottomSheet; - @NonNull + @Nullable private MapButtonsController mMapButtonsController; private boolean mIsTabletLayout; @@ -188,6 +190,7 @@ public class MwmActivity extends BaseMwmFragmentActivity @SuppressWarnings("NotNullFieldNotInitialized") @NonNull private PlacePageController mPlacePageController; + private MapButtonsController.LayoutMode mCurrentLayoutMode; private String mDonatesUrl; @@ -378,6 +381,11 @@ public class MwmActivity extends BaseMwmFragmentActivity if (savedInstanceState != null) { mLocationErrorDialogAnnoying = savedInstanceState.getBoolean(EXTRA_LOCATION_DIALOG_IS_ANNOYING); + mCurrentLayoutMode = MapButtonsController.LayoutMode.values()[savedInstanceState.getInt(EXTRA_CURRENT_LAYOUT_MODE)]; + } + else + { + mCurrentLayoutMode = MapButtonsController.LayoutMode.regular; } mIsTabletLayout = getResources().getBoolean(R.bool.tabletLayout); @@ -429,7 +437,6 @@ public class MwmActivity extends BaseMwmFragmentActivity private ArrayList getMainMenuItems() { ArrayList items = new ArrayList<>(); - items.add(new MenuBottomSheetItem(R.string.help, R.drawable.ic_question_mark, this::showHelp)); items.add(new MenuBottomSheetItem(R.string.placepage_add_place_button, R.drawable.ic_plus, this::onAddPlaceOptionSelected)); items.add(new MenuBottomSheetItem( R.string.download_maps, @@ -602,17 +609,32 @@ public class MwmActivity extends BaseMwmFragmentActivity return mMapFragment != null && mMapFragment.isAdded(); } + private void initNavigationButtons() { + initNavigationButtons(mCurrentLayoutMode); + } - final View frame = findViewById(R.id.navigation_buttons); - mMapButtonsController = new MapButtonsController(frame, - this, - this::onMapButtonClick, - (v) -> closeSearchToolbar(true, true), - mPlacePageController); - // FIXME For some reason the first onResume does not make the badge appear - new Handler().postDelayed(() -> mMapButtonsController.updateMarker(this), 100); + private void initNavigationButtons(MapButtonsController.LayoutMode layoutMode) + { + if (mMapButtonsController == null || mMapButtonsController.getLayoutMode() != layoutMode) + { + mCurrentLayoutMode = layoutMode; + + mMapButtonsController = new MapButtonsController(); + mMapButtonsController.init( + layoutMode, + LocationHelper.INSTANCE.getMyPositionMode(), + this::onMapButtonClick, + (v) -> closeSearchToolbar(true, true), + mPlacePageController, + this::adjustBottomWidgets); + + + FragmentTransaction transaction = getSupportFragmentManager() + .beginTransaction().replace(R.id.map_buttons, mMapButtonsController); + transaction.commit(); + } } void onMapButtonClick(MapButtonsController.MapButtons button) @@ -646,6 +668,9 @@ public class MwmActivity extends BaseMwmFragmentActivity closeFloatingPanels(); showMainMenuBottomSheet(); break; + case help: + showHelp(); + break; } } @@ -833,6 +858,7 @@ public class MwmActivity extends BaseMwmFragmentActivity RoutingController.get().onSaveState(); outState.putBoolean(EXTRA_LOCATION_DIALOG_IS_ANNOYING, mLocationErrorDialogAnnoying); + outState.putInt(EXTRA_CURRENT_LAYOUT_MODE, mCurrentLayoutMode.ordinal()); if (!isChangingConfigurations()) RoutingController.get().saveRoute(); @@ -1018,7 +1044,7 @@ public class MwmActivity extends BaseMwmFragmentActivity mOnmapDownloader.onResume(); mNavigationController.onActivityResumed(this); - mMapButtonsController.onResume(this); + mMapButtonsController.onResume(); mPlacePageController.onActivityResumed(this); } @@ -1231,11 +1257,20 @@ public class MwmActivity extends BaseMwmFragmentActivity MapFragment.nativeCompassUpdated(compass.getNorth(), true); } - public void adjustBottomWidgets(int offsetY) + public void adjustBottomWidgets() { if (mMapFragment == null || !mMapFragment.isAdded()) return; + int mapButtonsHeight = 0; + int mainMenuHeight = 0; + if (mMapButtonsController != null) + mapButtonsHeight = (int) mMapButtonsController.getBottomButtonsHeight(); + if (mMainMenu != null) + mainMenuHeight = mMainMenu.getMenuHeight(); + + int offsetY = Math.max(mapButtonsHeight, mainMenuHeight); + mMapFragment.setupBottomWidgetsOffset(offsetY); } @@ -1389,8 +1424,6 @@ public class MwmActivity extends BaseMwmFragmentActivity public void onRoutingPlanStartAnimate(boolean show) { int totalHeight = calcFloatingViewsOffset(); - - mMapButtonsController.setTopLimit(!show ? 0 : totalHeight); adjustCompassAndTraffic(!show ? UiUtils.getStatusBarHeight(getApplicationContext()) : totalHeight); } @@ -1425,7 +1458,6 @@ public class MwmActivity extends BaseMwmFragmentActivity if (mIsTabletLayout) { adjustCompassAndTraffic(UiUtils.getStatusBarHeight(getApplicationContext())); - mMapButtonsController.setTopLimit(0); } else { @@ -1508,6 +1540,7 @@ public class MwmActivity extends BaseMwmFragmentActivity mRoutingPlanInplaceController.hideDrivingOptionsView(); mNavigationController.stop(this); + initNavigationButtons(MapButtonsController.LayoutMode.regular); } @Override @@ -1516,18 +1549,30 @@ public class MwmActivity extends BaseMwmFragmentActivity closeFloatingToolbarsAndPanels(true); ThemeSwitcher.INSTANCE.restart(isMapRendererActive()); mNavigationController.start(this); + initNavigationButtons(MapButtonsController.LayoutMode.navigation); } @Override public void onPlanningCancelled() { closeFloatingToolbarsAndPanels(true); + initNavigationButtons(MapButtonsController.LayoutMode.regular); } @Override public void onPlanningStarted() { closeFloatingToolbarsAndPanels(true); + initNavigationButtons(MapButtonsController.LayoutMode.planning); + } + + @Override + public void onResetToPlanningState() + { + closeFloatingToolbarsAndPanels(true); + ThemeSwitcher.INSTANCE.restart(isMapRendererActive()); + mNavigationController.stop(this); + initNavigationButtons(MapButtonsController.LayoutMode.planning); } @Override @@ -1542,12 +1587,6 @@ public class MwmActivity extends BaseMwmFragmentActivity closePlacePage(); } - @Override - public void onResetToPlanningState() - { - closePlacePage(); - } - @Override public void onBuiltRoute() { diff --git a/android/src/com/mapswithme/maps/maplayer/MapButtonsController.java b/android/src/com/mapswithme/maps/maplayer/MapButtonsController.java index 39ff286e21..132350ca02 100644 --- a/android/src/com/mapswithme/maps/maplayer/MapButtonsController.java +++ b/android/src/com/mapswithme/maps/maplayer/MapButtonsController.java @@ -1,15 +1,17 @@ package com.mapswithme.maps.maplayer; -import android.app.Activity; -import android.content.res.TypedArray; +import android.content.Context; import android.os.Bundle; +import android.util.TypedValue; +import android.view.LayoutInflater; import android.view.View; -import android.widget.RelativeLayout; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.OptIn; -import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; import com.google.android.material.badge.BadgeDrawable; import com.google.android.material.badge.BadgeUtils; import com.google.android.material.floatingactionbutton.FloatingActionButton; @@ -22,81 +24,138 @@ import com.mapswithme.maps.widget.placepage.PlacePageController; import com.mapswithme.util.Config; import com.mapswithme.util.UiUtils; -public class MapButtonsController -{ - @NonNull - private final View mButtonsFrame; - @NonNull - private final View mZoomFrame; - @NonNull - private final FloatingActionButton mLayersButton; - @NonNull - private final View myPosition; - @NonNull - private final View mBookmarksButton; - @NonNull - private final View mMenuButton; - @NonNull - private final View mSearchButton; - @Nullable - private final MyPositionButton mNavMyPosition; - @NonNull - private final MapLayersController mToggleMapLayerController; - @NonNull - private final SearchWheel mSearchWheel; - @NonNull - private BadgeDrawable mBadgeDrawable; +import java.util.HashMap; +import java.util.Map; - private final PlacePageController mPlacePageController; - private final float mBottomMargin; - private final float mButtonWidth; - private float mTopLimit; +public class MapButtonsController extends Fragment +{ + Map mButtonsMap; + private View mFrame; + private View mInnerLeftButtonsFrame; + private View mInnerRightButtonsFrame; + @Nullable + private View mBottomButtonsFrame; + @Nullable + private MapLayersController mToggleMapLayerController; + + @Nullable + private MyPositionButton mNavMyPosition; + private SearchWheel mSearchWheel; + private BadgeDrawable mBadgeDrawable; private float mContentHeight; private float mContentWidth; - public MapButtonsController(@NonNull View frame, AppCompatActivity activity, MapButtonClickListener mapButtonClickListener, @NonNull View.OnClickListener onSearchCanceledListener, PlacePageController placePageController) + private MapButtonClickListener mMapButtonClickListener; + private View.OnClickListener mOnSearchCanceledListener; + private PlacePageController mPlacePageController; + private OnBottomButtonsHeightChangedListener mOnBottomButtonsHeightChangedListener; + + private LayoutMode mLayoutMode; + private int mMyPositionMode; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - mButtonsFrame = frame.findViewById(R.id.navigation_buttons_inner); - mZoomFrame = frame.findViewById(R.id.zoom_buttons_container); - mPlacePageController = placePageController; - frame.findViewById(R.id.nav_zoom_in) - .setOnClickListener((v) -> mapButtonClickListener.onClick(MapButtons.zoomIn)); - frame.findViewById(R.id.nav_zoom_out) - .setOnClickListener((v) -> mapButtonClickListener.onClick(MapButtons.zoomOut)); - mBookmarksButton = frame.findViewById(R.id.btn_bookmarks); - mBookmarksButton.setOnClickListener((v) -> mapButtonClickListener.onClick(MapButtons.bookmarks)); - mMenuButton = frame.findViewById(R.id.menu_button); - mMenuButton.setOnClickListener((v) -> mapButtonClickListener.onClick(MapButtons.menu)); - myPosition = frame.findViewById(R.id.my_position); - mNavMyPosition = new MyPositionButton(myPosition, (v) -> mapButtonClickListener.onClick(MapButtons.myPosition)); + if (mLayoutMode == LayoutMode.navigation) + mFrame = inflater.inflate(R.layout.map_buttons_layout_navigation, container, false); + else if (mLayoutMode == LayoutMode.planning) + mFrame = inflater.inflate(R.layout.map_buttons_layout_planning, container, false); + else + mFrame = inflater.inflate(R.layout.map_buttons_layout_regular, container, false); - mLayersButton = frame.findViewById(R.id.layers_button); - mToggleMapLayerController = new MapLayersController(mLayersButton, - () -> mapButtonClickListener.onClick(MapButtons.toggleMapLayer), activity); + mInnerLeftButtonsFrame = mFrame.findViewById(R.id.map_buttons_inner_left); + mInnerRightButtonsFrame = mFrame.findViewById(R.id.map_buttons_inner_right); + mBottomButtonsFrame = mFrame.findViewById(R.id.map_buttons_bottom); + View zoomFrame = mFrame.findViewById(R.id.zoom_buttons_container); + mFrame.findViewById(R.id.nav_zoom_in) + .setOnClickListener((v) -> mMapButtonClickListener.onClick(MapButtons.zoomIn)); + mFrame.findViewById(R.id.nav_zoom_out) + .setOnClickListener((v) -> mMapButtonClickListener.onClick(MapButtons.zoomOut)); + View bookmarksButton = mFrame.findViewById(R.id.btn_bookmarks); + bookmarksButton.setOnClickListener((v) -> mMapButtonClickListener.onClick(MapButtons.bookmarks)); + View myPosition = mFrame.findViewById(R.id.my_position); + mNavMyPosition = new MyPositionButton(myPosition, mMyPositionMode, (v) -> mMapButtonClickListener.onClick(MapButtons.myPosition)); - mSearchWheel = new SearchWheel(frame, (v) -> mapButtonClickListener.onClick(MapButtons.search), onSearchCanceledListener); - mSearchButton = frame.findViewById(R.id.btn_search); + // Some buttons do not exist in navigation mode + FloatingActionButton layersButton = mFrame.findViewById(R.id.layers_button); + if (layersButton != null) + { + mToggleMapLayerController = new MapLayersController(layersButton, + () -> mMapButtonClickListener.onClick(MapButtons.toggleMapLayer), requireActivity()); + } + View menuButton = mFrame.findViewById(R.id.menu_button); + if (menuButton != null) + { + menuButton.setOnClickListener((v) -> mMapButtonClickListener.onClick(MapButtons.menu)); + menuButton.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + updateMenuBadge(); + menuButton.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + }); + } + View helpButton = mFrame.findViewById(R.id.help_button); + if (helpButton != null) + helpButton.setOnClickListener((v) -> mMapButtonClickListener.onClick(MapButtons.help)); + + mSearchWheel = new SearchWheel(mFrame, (v) -> mMapButtonClickListener.onClick(MapButtons.search), mOnSearchCanceledListener); + View searchButton = mFrame.findViewById(R.id.btn_search); // Used to get the maximum height the buttons will evolve in - frame.addOnLayoutChangeListener(new MapButtonsController.ContentViewLayoutChangeListener(frame)); - mBottomMargin = ((RelativeLayout.LayoutParams) mButtonsFrame.getLayoutParams()).bottomMargin; + mFrame.addOnLayoutChangeListener(new MapButtonsController.ContentViewLayoutChangeListener(mFrame)); - TypedArray a = frame.getContext().getTheme().obtainStyledAttributes( - R.style.MwmWidget_MapButton, - new int[] { R.attr.fabCustomSize }); - mButtonWidth = a.getDimension(0, 0); - a.recycle(); + mButtonsMap = new HashMap<>(); + mButtonsMap.put(MapButtons.zoom, zoomFrame); + mButtonsMap.put(MapButtons.myPosition, myPosition); + mButtonsMap.put(MapButtons.bookmarks, bookmarksButton); + mButtonsMap.put(MapButtons.search, searchButton); + + if (layersButton != null) + mButtonsMap.put(MapButtons.toggleMapLayer, layersButton); + if (menuButton != null) + mButtonsMap.put(MapButtons.menu, menuButton); + if (helpButton != null) + mButtonsMap.put(MapButtons.help, helpButton); + return mFrame; + } + + @Override + public void onStart() + { + super.onStart(); + showMapButtons(true); + } + + public LayoutMode getLayoutMode() + { + return mLayoutMode; + } + + public void init(LayoutMode layoutMode, int myPositionMode, MapButtonClickListener mapButtonClickListener, @NonNull View.OnClickListener onSearchCanceledListener, PlacePageController placePageController, OnBottomButtonsHeightChangedListener onBottomButtonsHeightChangedListener) + { + mLayoutMode = layoutMode; + mMyPositionMode = myPositionMode; + mMapButtonClickListener = mapButtonClickListener; + mOnSearchCanceledListener = onSearchCanceledListener; + mPlacePageController = placePageController; + mOnBottomButtonsHeightChangedListener = onBottomButtonsHeightChangedListener; } public void showButton(boolean show, MapButtonsController.MapButtons button) { + View buttonView = mButtonsMap.get(button); + if (buttonView == null) + return; switch (button) { case zoom: - UiUtils.showIf(show && Config.showZoomButtons(), mZoomFrame); + UiUtils.showIf(show && Config.showZoomButtons(), buttonView); break; case toggleMapLayer: - mToggleMapLayerController.showButton(show && !isInNavigationMode()); + if (mToggleMapLayerController != null) + mToggleMapLayerController.showButton(show && !isInNavigationMode()); break; case myPosition: if (mNavMyPosition != null) @@ -105,74 +164,106 @@ public class MapButtonsController case search: mSearchWheel.show(show); case bookmarks: - UiUtils.showIf(show, mBookmarksButton); case menu: - UiUtils.showIf(show, mMenuButton); + UiUtils.showIf(show, buttonView); } } - @OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class) - public void updateMarker(@NonNull Activity activity) + private static int dpToPx(float dp, Context context) { - final UpdateInfo info = MapManager.nativeGetUpdateInfo(null); - final int count = (info == null ? 0 : info.filesCount); - BadgeUtils.detachBadgeDrawable(mBadgeDrawable, mMenuButton); - mBadgeDrawable = BadgeDrawable.create(activity); - mBadgeDrawable.setHorizontalOffset(30); - mBadgeDrawable.setVerticalOffset(20); - mBadgeDrawable.setNumber(count); - mBadgeDrawable.setVisible(count > 0); - BadgeUtils.attachBadgeDrawable(mBadgeDrawable, mMenuButton); + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } - private boolean isScreenWideEnough() + @OptIn(markerClass = com.google.android.material.badge.ExperimentalBadgeUtils.class) + public void updateMenuBadge() { - return mContentWidth > (mPlacePageController.getPlacePageWidth() + 2 * mButtonWidth); + View menuButton = mButtonsMap.get(MapButtons.menu); + Context context = getContext(); + if (menuButton == null || context == null) + return; + final UpdateInfo info = MapManager.nativeGetUpdateInfo(null); + final int count = (info == null ? 0 : info.filesCount); + final int verticalOffset = dpToPx(8, context) + dpToPx(Integer.toString(count).length() * 5, context); + BadgeUtils.detachBadgeDrawable(mBadgeDrawable, menuButton); + mBadgeDrawable = BadgeDrawable.create(context); + mBadgeDrawable.setMaxCharacterCount(3); + mBadgeDrawable.setHorizontalOffset(verticalOffset); + mBadgeDrawable.setVerticalOffset(dpToPx(9, context)); + mBadgeDrawable.setNumber(count); + mBadgeDrawable.setVisible(count > 0); + BadgeUtils.attachBadgeDrawable(mBadgeDrawable, menuButton); + } + + private boolean isBehindPlacePage(View v) + { + return !(mContentWidth / 2 > (mPlacePageController.getPlacePageWidth() / 2.0) + v.getWidth()); + } + + private boolean isMoving(View v) + { + return v.getTranslationY() < 0; } public void move(float translationY) { - if (mContentHeight == 0 || isScreenWideEnough()) + if (mContentHeight == 0) return; - // Move the buttons container to follow the place page - final float translation = mBottomMargin + translationY - mContentHeight; - final float appliedTranslation = translation <= 0 ? translation : 0; - mButtonsFrame.setTranslationY(appliedTranslation); + // Move the buttons containers to follow the place page + if (mInnerRightButtonsFrame != null && + (isBehindPlacePage(mInnerRightButtonsFrame) || isMoving(mInnerRightButtonsFrame))) + applyMove(mInnerRightButtonsFrame, translationY); + if (mInnerLeftButtonsFrame != null && + (isBehindPlacePage(mInnerLeftButtonsFrame) || isMoving(mInnerLeftButtonsFrame))) + applyMove(mInnerLeftButtonsFrame, translationY); + } - updateButtonsVisibility(appliedTranslation); + private void applyMove(View frame, float translationY) + { + final float rightTranslation = translationY - frame.getBottom(); + final float appliedTranslation = rightTranslation <= 0 ? rightTranslation : 0; + frame.setTranslationY(appliedTranslation); + updateButtonsVisibility(appliedTranslation, frame); } public void updateButtonsVisibility() { - updateButtonsVisibility(mButtonsFrame.getTranslationY()); + updateButtonsVisibility(mInnerLeftButtonsFrame.getTranslationY(), mInnerLeftButtonsFrame); + updateButtonsVisibility(mInnerRightButtonsFrame.getTranslationY(), mInnerRightButtonsFrame); } - private void updateButtonsVisibility(final float translation) + private void updateButtonsVisibility(final float translation, @Nullable View parent) { - showButton(getViewTopOffset(translation, mZoomFrame) > 0, MapButtons.zoom); - showButton(getViewTopOffset(translation, mSearchButton) > 0, MapButtons.search); - showButton(getViewTopOffset(translation, mLayersButton) > 0, MapButtons.toggleMapLayer); - showButton(getViewTopOffset(translation, myPosition) > 0, MapButtons.myPosition); - showButton(getViewTopOffset(translation, mMenuButton) > 0, MapButtons.menu); - showButton(getViewTopOffset(translation, mBookmarksButton) > 0, MapButtons.bookmarks); + if (parent == null) + return; + for (Map.Entry entry : mButtonsMap.entrySet()) + { + final View button = entry.getValue(); + if (button.getParent() == parent) + showButton(getViewTopOffset(translation, button) > 0, entry.getKey()); + } } - public void setTopLimit(float limit) + public float getBottomButtonsHeight() { - mTopLimit = limit; - updateButtonsVisibility(); + if (mBottomButtonsFrame != null && mFrame != null && UiUtils.isVisible(mFrame)) + { + return mBottomButtonsFrame.getMeasuredHeight(); + } + else + return 0; } public void showMapButtons(boolean show) { if (show) { - UiUtils.show(mButtonsFrame); + UiUtils.show(mFrame); showButton(true, MapButtons.zoom); } else - UiUtils.hide(mButtonsFrame); + UiUtils.hide(mFrame); + mOnBottomButtonsHeightChangedListener.OnBottomButtonsHeightChanged(); } private boolean isInNavigationMode() @@ -182,7 +273,8 @@ public class MapButtonsController public void toggleMapLayer(@NonNull Mode mode) { - mToggleMapLayerController.toggleMode(mode); + if (mToggleMapLayerController != null) + mToggleMapLayerController.toggleMode(mode); } public void updateNavMyPositionButton(int newMode) @@ -193,14 +285,13 @@ public class MapButtonsController private int getViewTopOffset(float translation, View v) { - return (int) (translation + v.getTop() - mTopLimit); + return (int) (translation + v.getTop()); } - public void onResume(@NonNull Activity activity) + public void onResume() { - + super.onResume(); mSearchWheel.onResume(); - updateMarker(activity); } public void resetSearch() @@ -218,6 +309,13 @@ public class MapButtonsController mSearchWheel.restoreState(savedInstanceState); } + public enum LayoutMode + { + regular, + planning, + navigation + } + public enum MapButtons { myPosition, @@ -227,7 +325,8 @@ public class MapButtonsController zoom, search, bookmarks, - menu + menu, + help } public interface MapButtonClickListener @@ -235,6 +334,11 @@ public class MapButtonsController void onClick(MapButtons button); } + public interface OnBottomButtonsHeightChangedListener + { + void OnBottomButtonsHeightChanged(); + } + private class ContentViewLayoutChangeListener implements View.OnLayoutChangeListener { @NonNull @@ -251,6 +355,7 @@ public class MapButtonsController { mContentHeight = bottom - top; mContentWidth = right - left; + mOnBottomButtonsHeightChangedListener.OnBottomButtonsHeightChanged(); mContentView.removeOnLayoutChangeListener(this); } } diff --git a/android/src/com/mapswithme/maps/maplayer/MapLayersController.java b/android/src/com/mapswithme/maps/maplayer/MapLayersController.java index de27df40b8..6cfe49f3d3 100644 --- a/android/src/com/mapswithme/maps/maplayer/MapLayersController.java +++ b/android/src/com/mapswithme/maps/maplayer/MapLayersController.java @@ -1,10 +1,10 @@ package com.mapswithme.maps.maplayer; +import android.app.Activity; import android.view.ViewGroup; import android.widget.ImageButton; import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; import com.mapswithme.maps.R; import com.mapswithme.util.Graphics; import com.mapswithme.util.UiUtils; @@ -14,7 +14,7 @@ import java.util.List; public class MapLayersController { @NonNull - private final AppCompatActivity mActivity; + private final Activity mActivity; @NonNull private final List mLayers; @NonNull @@ -24,7 +24,7 @@ public class MapLayersController @NonNull private Mode mCurrentLayer; - public MapLayersController(@NonNull ImageButton layersButton, @NonNull OnShowMenuListener onShowMenuListener, @NonNull AppCompatActivity activity) + public MapLayersController(@NonNull ImageButton layersButton, @NonNull OnShowMenuListener onShowMenuListener, @NonNull Activity activity) { mActivity = activity; mLayersButton = layersButton; diff --git a/android/src/com/mapswithme/maps/maplayer/SearchWheel.java b/android/src/com/mapswithme/maps/maplayer/SearchWheel.java index bcb4171338..d50ec6f226 100644 --- a/android/src/com/mapswithme/maps/maplayer/SearchWheel.java +++ b/android/src/com/mapswithme/maps/maplayer/SearchWheel.java @@ -27,8 +27,10 @@ public class SearchWheel implements View.OnClickListener private static final String EXTRA_CURRENT_OPTION = "extra_current_option"; private final View mFrame; - private final View mSearchLayout; + @Nullable + private View mSearchLayout; private final ImageView mSearchButton; + @Nullable private final View mTouchInterceptor; private boolean mIsExpanded; @@ -109,26 +111,40 @@ public class SearchWheel implements View.OnClickListener mOnSearchPressedListener = onSearchPressedListener; mOnSearchCanceledListener = onSearchCanceledListener; mTouchInterceptor = mFrame.findViewById(R.id.touch_interceptor); - mTouchInterceptor.setOnClickListener(this); + if (mTouchInterceptor != null) + mTouchInterceptor.setOnClickListener(this); mSearchButton = mFrame.findViewById(R.id.btn_search); mSearchButton.setOnClickListener(this); - mSearchLayout = mFrame.findViewById(R.id.search_frame); - if (UiUtils.isLandscape(mFrame.getContext())) - { - UiUtils.waitLayout(mSearchLayout, () -> { - mSearchLayout.setPivotX(0); - mSearchLayout.setPivotY(mSearchLayout.getMeasuredHeight() / 2); - }); - } - for (SearchOption searchOption : SearchOption.values()) - mFrame.findViewById(searchOption.mResId).setOnClickListener(this); refreshSearchVisibility(); } + private @Nullable View getSearchLayout() + { + if (mSearchLayout == null) + { + mSearchLayout = mFrame.findViewById(R.id.search_frame); + if (mSearchLayout != null) + { + if (UiUtils.isLandscape(mFrame.getContext())) + { + UiUtils.waitLayout(mSearchLayout, () -> { + mSearchLayout.setPivotX(0); + mSearchLayout.setPivotY(mSearchLayout.getMeasuredHeight() / 2); + }); + } + for (SearchOption searchOption : SearchOption.values()) + mFrame.findViewById(searchOption.mResId).setOnClickListener(this); + } + } + return mSearchLayout; + } + public void show(boolean show) { UiUtils.showIf(show, mSearchButton); - UiUtils.showIf(show && mIsExpanded, mSearchLayout); + View searchLayout = getSearchLayout(); + if (searchLayout != null) + UiUtils.showIf(show && mIsExpanded, searchLayout); } public void saveState(@NonNull Bundle outState) @@ -169,42 +185,52 @@ public class SearchWheel implements View.OnClickListener private void toggleSearchLayout() { - final int animRes; - if (mIsExpanded) + View searchLayout = getSearchLayout(); + if (searchLayout != null) { - animRes = R.animator.show_zoom_out_alpha; - } - else - { - animRes = R.animator.show_zoom_in_alpha; - UiUtils.show(mSearchLayout); - } - mIsExpanded = !mIsExpanded; - final Animator animator = AnimatorInflater.loadAnimator(mSearchLayout.getContext(), animRes); - animator.setTarget(mSearchLayout); - animator.start(); - UiUtils.visibleIf(mIsExpanded, mTouchInterceptor); - animator.addListener(new UiUtils.SimpleAnimatorListener() - { - @Override - public void onAnimationEnd(Animator animation) + final int animRes; + if (mIsExpanded) { - refreshSearchVisibility(); + animRes = R.animator.show_zoom_out_alpha; } - }); + else + { + animRes = R.animator.show_zoom_in_alpha; + UiUtils.show(mSearchLayout); + } + mIsExpanded = !mIsExpanded; + final Animator animator = AnimatorInflater.loadAnimator(mSearchLayout.getContext(), animRes); + animator.setTarget(mSearchLayout); + animator.start(); + if (mTouchInterceptor != null) + UiUtils.visibleIf(mIsExpanded, mTouchInterceptor); + animator.addListener(new UiUtils.SimpleAnimatorListener() + { + @Override + public void onAnimationEnd(Animator animation) + { + refreshSearchVisibility(); + } + }); + } } private void refreshSearchVisibility() { - for (SearchOption searchOption : SearchOption.values()) - UiUtils.visibleIf(mIsExpanded, mSearchLayout.findViewById(searchOption.mResId)); - - UiUtils.visibleIf(mIsExpanded, mSearchLayout, mTouchInterceptor); - - if (mIsExpanded) + View searchLayout = getSearchLayout(); + if (searchLayout != null) { - UiThread.cancelDelayedTasks(mCloseRunnable); - UiThread.runLater(mCloseRunnable, CLOSE_DELAY_MILLIS); + for (SearchOption searchOption : SearchOption.values()) + UiUtils.visibleIf(mIsExpanded, searchLayout.findViewById(searchOption.mResId)); + + if (mTouchInterceptor != null) + UiUtils.visibleIf(mIsExpanded, mSearchLayout, mTouchInterceptor); + + if (mIsExpanded) + { + UiThread.cancelDelayedTasks(mCloseRunnable); + UiThread.runLater(mCloseRunnable, CLOSE_DELAY_MILLIS); + } } } diff --git a/android/src/com/mapswithme/maps/routing/RoutingController.java b/android/src/com/mapswithme/maps/routing/RoutingController.java index 39fd5c0efa..03e7e78cb7 100644 --- a/android/src/com/mapswithme/maps/routing/RoutingController.java +++ b/android/src/com/mapswithme/maps/routing/RoutingController.java @@ -464,7 +464,7 @@ public class RoutingController implements Initializable setState(State.NAVIGATION); - cancelPlanning(); + cancelPlanning(false); startNavigation(); Framework.nativeFollowRoute(); @@ -477,7 +477,7 @@ public class RoutingController implements Initializable build(); if (mContainer != null) mContainer.onAddedStop(); - backToPlaningStateIfNavigating(); + resetToPlanningStateIfNavigating(); } public void removeStop(@NonNull MapObject mapObject) @@ -491,7 +491,7 @@ public class RoutingController implements Initializable build(); if (mContainer != null) mContainer.onRemovedStop(); - backToPlaningStateIfNavigating(); + resetToPlanningStateIfNavigating(); } /** @@ -502,28 +502,18 @@ public class RoutingController implements Initializable if (isNavigating()) { build(); + setState(State.PREPARE); + cancelNavigation(false); + startPlanning(); + if (mContainer != null) + mContainer.updateMenu(); if (mContainer != null) mContainer.onResetToPlanningState(); - backToPlaningStateIfNavigating(); return true; } return false; } - private void backToPlaningStateIfNavigating() - { - if (!isNavigating()) - return; - - setState(State.PREPARE); - cancelNavigation(); - startPlanning(); - if (mContainer != null) - { - mContainer.updateMenu(); - } - } - private void removeIntermediatePoints() { Framework.nativeRemoveIntermediateRoutePoints(); @@ -617,7 +607,7 @@ public class RoutingController implements Initializable Logger.d(TAG, "cancel: planning"); cancelInternal(); - cancelPlanning(); + cancelPlanning(true); return true; } @@ -626,7 +616,7 @@ public class RoutingController implements Initializable Logger.d(TAG, "cancel: navigating"); cancelInternal(); - cancelNavigation(); + cancelNavigation(true); if (mContainer != null) { mContainer.updateMenu(); @@ -638,16 +628,15 @@ public class RoutingController implements Initializable return false; } - public void startPlanning() + private void startPlanning() { if (mContainer != null) { showRoutePlan(); - mContainer.onPlanningStarted(); } } - public void startPlanning(final @Nullable MapObject startPoint, final @Nullable MapObject endPoint) + private void startPlanning(final @Nullable MapObject startPoint, final @Nullable MapObject endPoint) { if (mContainer != null) { @@ -656,16 +645,17 @@ public class RoutingController implements Initializable } } - public void cancelPlanning() + private void cancelPlanning(boolean fireEvent) { if (mContainer != null) { mContainer.showRoutePlan(false, null); - mContainer.onPlanningCancelled(); + if (fireEvent) + mContainer.onPlanningCancelled(); } } - public void startNavigation() + private void startNavigation() { if (mContainer != null) { @@ -674,12 +664,13 @@ public class RoutingController implements Initializable } } - public void cancelNavigation() + private void cancelNavigation(boolean fireEvent) { if (mContainer != null) { mContainer.showNavigation(false); - mContainer.onNavigationCancelled(); + if (fireEvent) + mContainer.onNavigationCancelled(); } } diff --git a/android/src/com/mapswithme/maps/widget/menu/MainMenu.java b/android/src/com/mapswithme/maps/widget/menu/MainMenu.java index 819b0c2cb2..92ac69dc73 100644 --- a/android/src/com/mapswithme/maps/widget/menu/MainMenu.java +++ b/android/src/com/mapswithme/maps/widget/menu/MainMenu.java @@ -7,13 +7,13 @@ import com.mapswithme.util.UiUtils; public class MainMenu { private final View mFrame; - private final OnMenuSizeChangeListener mOnMenuSizeChangeListener; + private final OnMenuSizeChangedListener mOnMenuSizeChangedListener; private int mMenuHeight; - public MainMenu(View frame, OnMenuSizeChangeListener onMenuSizeChangeListener) + public MainMenu(View frame, OnMenuSizeChangedListener onMenuSizeChangedListener) { mFrame = frame; - mOnMenuSizeChangeListener = onMenuSizeChangeListener; + mOnMenuSizeChangedListener = onMenuSizeChangedListener; mFrame.addOnLayoutChangeListener(new MainMenu.FrameLayoutChangeListener()); setState(State.MENU, false); } @@ -29,12 +29,12 @@ public class MainMenu return; UiUtils.showIf(show, mFrame); - notifyHeight(); + mOnMenuSizeChangedListener.OnMenuSizeChange(); } - private void notifyHeight() + public int getMenuHeight() { - mOnMenuSizeChangeListener.OnMenuSizeChange(UiUtils.isVisible(mFrame) ? mMenuHeight : 0); + return UiUtils.isVisible(mFrame) ? mMenuHeight : 0; } public View getFrame() @@ -57,9 +57,9 @@ public class MainMenu BOOKMARKS } - public interface OnMenuSizeChangeListener + public interface OnMenuSizeChangedListener { - void OnMenuSizeChange(int newHeight); + void OnMenuSizeChange(); } private class FrameLayoutChangeListener implements View.OnLayoutChangeListener @@ -69,7 +69,7 @@ public class MainMenu int oldTop, int oldRight, int oldBottom) { mMenuHeight = bottom - top; - notifyHeight(); + mOnMenuSizeChangedListener.OnMenuSizeChange(); } } } diff --git a/android/src/com/mapswithme/maps/widget/menu/MyPositionButton.java b/android/src/com/mapswithme/maps/widget/menu/MyPositionButton.java index fe02ffb6cc..eff3bb3c2a 100644 --- a/android/src/com/mapswithme/maps/widget/menu/MyPositionButton.java +++ b/android/src/com/mapswithme/maps/widget/menu/MyPositionButton.java @@ -29,13 +29,14 @@ public class MyPositionButton private final int mFollowPaddingShift; - public MyPositionButton(@NonNull View button, @NonNull View.OnClickListener listener) + public MyPositionButton(@NonNull View button, int myPositionMode, @NonNull View.OnClickListener listener) { mButton = (FloatingActionButton) button; mVisible = UiUtils.isVisible(mButton); mButton.setOnClickListener(listener); mIcons.clear(); mFollowPaddingShift = (int) (FOLLOW_SHIFT * button.getResources().getDisplayMetrics().density); + update(myPositionMode); } @SuppressWarnings("deprecation")