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")