[android] Migrate layers menu and main menu to MenuBottomSheetFragment

Signed-off-by: Arnaud Vergnet <arnaud.vergnet@mailo.com>
This commit is contained in:
Arnaud Vergnet 2022-03-13 22:26:01 +01:00 committed by Viktor Govako
parent 97a76c2961
commit 0d90ff0cf2
42 changed files with 404 additions and 1248 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_toggle_map_layer_btn_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/bg_toggle_map_layer_btn_selected" android:state_selected="true"/>
<item android:drawable="@drawable/bg_toggle_map_layer_btn_default"/>
</selector>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_toggle_map_layer_btn_pressed_dark" android:state_pressed="true"/>
<item android:drawable="@drawable/bg_toggle_map_layer_btn_selected_dark" android:state_selected="true"/>
<item android:drawable="@drawable/bg_toggle_map_layer_btn_default_dark"/>
</selector>

View file

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="@dimen/margin_double_plus"
android:width="@dimen/margin_double_plus">
<solid android:color="@color/black_4"/>
</shape>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_circle"/>
<item
android:drawable="@drawable/ic_layers_light_on"
android:left="@dimen/margin_base_plus_quarter"
android:right="@dimen/margin_base_plus_quarter"
android:top="@dimen/margin_base_plus_quarter"
android:bottom="@dimen/margin_base_plus_quarter"/>
</layer-list>

View file

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="@dimen/margin_double_plus"
android:width="@dimen/margin_double_plus">
<solid android:color="@color/white_4"/>
</shape>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_circle_night"/>
<item
android:drawable="@drawable/ic_layers_dark_on"
android:left="@dimen/margin_base_plus_quarter"
android:right="@dimen/margin_base_plus_quarter"
android:top="@dimen/margin_base_plus_quarter"
android:bottom="@dimen/margin_base_plus_quarter"/>
</layer-list>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_circle_pressed"/>
<item
android:drawable="@drawable/ic_layers_light_on"
android:left="@dimen/margin_base_plus_quarter"
android:right="@dimen/margin_base_plus_quarter"
android:top="@dimen/margin_base_plus_quarter"
android:bottom="@dimen/margin_base_plus_quarter"/>
</layer-list>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_circle_pressed_night"/>
<item
android:drawable="@drawable/ic_layers_dark_on"
android:left="@dimen/margin_base_plus_quarter"
android:right="@dimen/margin_base_plus_quarter"
android:top="@dimen/margin_base_plus_quarter"
android:bottom="@dimen/margin_base_plus_quarter"/>
</layer-list>

View file

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="@dimen/margin_double_plus"
android:width="@dimen/margin_double_plus">
<solid android:color="@color/base_accent"/>
</shape>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_circle"/>
<item
android:drawable="@drawable/ic_layers_off"
android:left="@dimen/margin_base_plus_quarter"
android:right="@dimen/margin_base_plus_quarter"
android:top="@dimen/margin_base_plus_quarter"
android:bottom="@dimen/margin_base_plus_quarter"/>
</layer-list>

View file

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:height="@dimen/margin_double_plus"
android:width="@dimen/margin_double_plus">
<solid android:color="@color/base_accent_night"/>
</shape>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/bg_circle_night"/>
<item
android:drawable="@drawable/ic_layers_off_night"
android:left="@dimen/margin_base_plus_quarter"
android:right="@dimen/margin_base_plus_quarter"
android:top="@dimen/margin_base_plus_quarter"
android:bottom="@dimen/margin_base_plus_quarter"/>
</layer-list>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_menu_sheet"
android:layout_width="@dimen/main_menu_bottom_sheet_width"
android:layout_height="wrap_content"
android:background="?windowBackgroundForced"
android:clickable="true"
android:focusable="true"
android:fillViewport="true"
app:behavior_defaultState="hidden"
app:behavior_skipAnchored="true"
app:behavior_skipCollapsed="true"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/menu_content" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -9,14 +9,14 @@
<ImageButton
android:id="@+id/traffic"
style="@style/MwmWidget.MapButton.Traffic"
style="@style/MwmWidget.MapButton.Layers"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="invisible"/>
<ImageButton
android:id="@+id/subway"
style="@style/MwmWidget.MapButton.Traffic"
style="@style/MwmWidget.MapButton.Layers"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="?attr/nav_bg_subway"
@ -24,7 +24,7 @@
<ImageButton
android:id="@+id/isolines"
style="@style/MwmWidget.MapButton.Traffic"
style="@style/MwmWidget.MapButton.Layers"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="?nav_bg_isolines"

View file

@ -42,14 +42,7 @@
android:visibility="gone"
tools:visibility="invisible"/>
<com.mapswithme.maps.widget.FadeView
android:id="@+id/fade_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:visibility="gone"/>
<include
<include
layout="@layout/layout_nav"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -92,5 +85,4 @@
<include layout="@layout/divider_horizontal"/>
</FrameLayout>
<include layout="@layout/elevation_profile_bottom_sheet" />
<include layout="@layout/main_menu_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -5,6 +5,11 @@
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/bottom_sheet_menu_header"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/bottomSheetTitle"
android:layout_width="wrap_content"

View file

@ -1,52 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:background="?attr/cardBackground"
android:paddingTop="@dimen/margin_quarter"
android:paddingBottom="@dimen/margin_quarter"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/сlose_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="@dimen/menu_list_item_height"
android:src="@drawable/ic_drop_down"
android:tint="@color/icon_tint"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
android:background="?attr/selectableItemBackgroundBorderless"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/layers_text"
android:minHeight="@dimen/menu_list_item_height"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@id/сlose_btn"
android:visibility="visible"
android:layout_marginStart="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:text="@string/layers_title"
android:textAppearance="@style/MwmTextAppearance.Body2"/>
android:textAppearance="?fontHeadline6" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_base"
android:minHeight="@dimen/toggle_map_layer_frame_height"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
app:layout_constraintTop_toBottomOf="@id/layers_text">
</androidx.recyclerview.widget.RecyclerView>
<View
app:layout_constraintBottom_toTopOf="@id/recycler"
android:background="?android:attr/listDivider"
android:layout_width="match_parent"
android:layout_height="@dimen/divider_height"/>
</androidx.constraintlayout.widget.ConstraintLayout>
android:paddingEnd="@dimen/margin_base" />
</LinearLayout>

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_menu_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?windowBackgroundForced"
android:clickable="true"
android:focusable="true"
android:fillViewport="true"
app:behavior_defaultState="hidden"
app:behavior_hideable="true"
app:behavior_skipAnchored="true"
app:behavior_skipCollapsed="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/menu_content" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -8,31 +8,32 @@
android:layoutDirection="ltr"
android:theme="?navButtonsTheme">
<ImageButton
android:id="@+id/layers_button"
style="@style/MwmWidget.MapButton.Layers"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="?toggleMapLayerBtnBg"
android:visibility="invisible"
tools:visibility="visible" />
<ImageButton
android:id="@+id/traffic"
style="@style/MwmWidget.MapButton.Traffic"
style="@style/MwmWidget.MapButton.Layers"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="invisible"
tools:src="@drawable/anim_traffic_loading"/>
tools:src="@drawable/anim_traffic_loading" />
<ImageButton
android:id="@+id/subway"
style="@style/MwmWidget.MapButton.Traffic"
style="@style/MwmWidget.MapButton.Layers"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="invisible"
android:background="?attr/nav_bg_subway"
tools:src="@drawable/anim_traffic_loading"/>
<ImageButton
android:id="@+id/isolines"
style="@style/MwmWidget.MapButton.Traffic"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="invisible"
android:background="?nav_bg_isolines"/>
<ImageButton
android:id="@+id/my_position"
style="@style/MwmWidget.MapButton"

View file

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?cardBackground"
android:orientation="vertical"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
android:paddingTop="@dimen/margin_base"
android:paddingBottom="@dimen/margin_half_plus">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/layers_title"
android:textAppearance="?fontHeadline6"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/layers_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
<include layout="@layout/list_divider" />
<include
layout="@layout/list_divider"
android:layout_width="match_parent"
android:layout_height="@dimen/divider_height"
android:layout_marginTop="@dimen/margin_half_plus" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?cardBackground"
android:orientation="vertical">
<TextView
android:id="@+id/add_place"
style="@style/MwmTheme.Menu.Content.ListItem"
android:drawableStart="@drawable/ic_plus"
android:text="@string/placepage_add_place_button"
tools:background="#40FF00FF" />
<FrameLayout
android:id="@+id/download_maps_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/download_maps"
style="@style/MwmTheme.Menu.Content.ListItem"
android:drawableStart="@drawable/ic_menu_download"
android:text="@string/download_maps"
tools:background="#2000FF00" />
<TextView
android:id="@+id/counter"
style="@style/MwmWidget.Counter"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="@dimen/margin_base"
android:visibility="gone"
tools:text="9999"
tools:visibility="visible" />
</FrameLayout>
<TextView
android:id="@+id/settings"
style="@style/MwmTheme.Menu.Content.ListItem"
android:drawableStart="@drawable/ic_menu_settings"
android:text="@string/settings"
tools:background="#20FF0000" />
<TextView
android:id="@+id/share"
style="@style/MwmTheme.Menu.Content.ListItem"
android:drawableStart="@drawable/ic_menu_share"
android:text="@string/share_my_location"
tools:background="#400FF000" />
</LinearLayout>
</LinearLayout>

View file

@ -17,7 +17,7 @@
<item name="android:tint">?iconTint</item>
</style>
<style name="MwmWidget.MapButton.Traffic">
<style name="MwmWidget.MapButton.Layers">
<item name="android:tint">@null</item>
</style>

View file

@ -16,7 +16,6 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.ImageButton;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
@ -45,7 +44,9 @@ import com.mapswithme.maps.dialog.AlertDialogCallback;
import com.mapswithme.maps.dialog.DialogUtils;
import com.mapswithme.maps.downloader.DownloaderActivity;
import com.mapswithme.maps.downloader.DownloaderFragment;
import com.mapswithme.maps.downloader.MapManager;
import com.mapswithme.maps.downloader.OnmapDownloader;
import com.mapswithme.maps.downloader.UpdateInfo;
import com.mapswithme.maps.editor.Editor;
import com.mapswithme.maps.editor.EditorActivity;
import com.mapswithme.maps.editor.EditorHostFragment;
@ -58,14 +59,11 @@ import com.mapswithme.maps.location.CompassData;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.maplayer.MapLayerCompositeController;
import com.mapswithme.maps.maplayer.Mode;
import com.mapswithme.maps.maplayer.OnIsolinesLayerToggleListener;
import com.mapswithme.maps.maplayer.ToggleMapLayerFragment;
import com.mapswithme.maps.maplayer.isolines.IsolinesManager;
import com.mapswithme.maps.maplayer.isolines.IsolinesState;
import com.mapswithme.maps.maplayer.subway.OnSubwayLayerToggleListener;
import com.mapswithme.maps.maplayer.subway.SubwayManager;
import com.mapswithme.maps.maplayer.traffic.OnTrafficLayerToggleListener;
import com.mapswithme.maps.maplayer.traffic.TrafficManager;
import com.mapswithme.maps.maplayer.traffic.widget.TrafficButton;
import com.mapswithme.maps.routing.NavigationController;
import com.mapswithme.maps.routing.RoutePointInfo;
import com.mapswithme.maps.routing.RoutingBottomMenuListener;
@ -84,13 +82,8 @@ import com.mapswithme.maps.settings.SettingsActivity;
import com.mapswithme.maps.settings.StoragePathManager;
import com.mapswithme.maps.settings.UnitLocale;
import com.mapswithme.maps.sound.TtsPlayer;
import com.mapswithme.maps.widget.FadeView;
import com.mapswithme.maps.widget.menu.BaseMenu;
import com.mapswithme.maps.widget.menu.MainMenu;
import com.mapswithme.maps.widget.menu.MainMenuOptionListener;
import com.mapswithme.maps.widget.menu.MenuController;
import com.mapswithme.maps.widget.menu.MenuControllerFactory;
import com.mapswithme.maps.widget.menu.MenuStateObserver;
import com.mapswithme.maps.widget.menu.MyPositionButton;
import com.mapswithme.maps.widget.placepage.PlacePageController;
import com.mapswithme.maps.widget.placepage.PlacePageData;
@ -104,9 +97,12 @@ import com.mapswithme.util.ThemeSwitcher;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.bottomsheet.MenuBottomSheetFragment;
import com.mapswithme.util.bottomsheet.MenuBottomSheetItem;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Stack;
@ -124,12 +120,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
RoutingBottomMenuListener,
BookmarkManager.BookmarksLoadingListener,
FloatingSearchToolbarController.SearchToolbarListener,
OnTrafficLayerToggleListener,
OnSubwayLayerToggleListener,
PlacePageController.SlideListener,
AlertDialogCallback, RoutingModeListener,
AppBackgroundTracker.OnTransitionListener,
OnIsolinesLayerToggleListener,
NoConnectionListener,
MapWidgetOffsetsProvider
{
@ -165,10 +158,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Nullable
private MapFragment mMapFragment;
@SuppressWarnings("NullableProblems")
@NonNull
private FadeView mFadeView;
@SuppressWarnings("NullableProblems")
@NonNull
private View mPositionChooser;
@ -189,6 +178,12 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Nullable
private MyPositionButton mNavMyPosition;
@NonNull
ToggleMapLayerFragment mToggleMapLayerFragment;
@NonNull
private MenuBottomSheetFragment mLayersBottomSheet;
@NonNull
private MenuBottomSheetFragment mMainMenuBottomSheet;
@Nullable
private NavigationButtonsAnimationController mNavAnimationController;
@SuppressWarnings("NullableProblems")
@ -217,9 +212,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@NonNull
private PlacePageController mPlacePageController;
@SuppressWarnings("NullableProblems")
@NonNull
private MenuController mMainMenuController;
public interface LeftAnimationTrackListener
{
@ -414,17 +406,14 @@ public class MwmActivity extends BaseMwmFragmentActivity
mPlacePageController.initialize(this);
mPlacePageController.onActivityCreated(this, savedInstanceState);
mMainMenuController = MenuControllerFactory.createMainMenuController(new MainMenuStateObserver(),
new MainMenuOptionSelectedListener(),
this);
mMainMenuController.initialize(findViewById(R.id.coordinator));
mSearchController = new FloatingSearchToolbarController(this, this);
mSearchController.getToolbar()
.getViewTreeObserver()
.addOnGlobalLayoutListener(new ToolbarLayoutChangeListener());
mSearchController.setVisibilityListener(this);
initBottomSheets();
boolean isLaunchByDeepLink = getIntent().getBooleanExtra(EXTRA_LAUNCH_BY_DEEP_LINK, false);
initViews(isLaunchByDeepLink);
@ -443,6 +432,34 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
}
private void initBottomSheets()
{
mToggleMapLayerFragment = new ToggleMapLayerFragment(this::onIsolinesLayerOptionSelected, this::onSubwayLayerOptionSelected);
mLayersBottomSheet = new MenuBottomSheetFragment(mToggleMapLayerFragment);
mMainMenuBottomSheet = new MenuBottomSheetFragment(mToggleMapLayerFragment, getMainMenuItems());
}
private int getDownloadMapsCounter()
{
UpdateInfo info = MapManager.nativeGetUpdateInfo(null);
return info == null ? 0 : info.filesCount;
}
private ArrayList<MenuBottomSheetItem> getMainMenuItems()
{
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
items.add(new MenuBottomSheetItem(R.string.placepage_add_place_button, R.drawable.ic_plus, this::onAddPlaceOptionSelected));
items.add(new MenuBottomSheetItem(
R.string.download_maps,
R.drawable.ic_download,
getDownloadMapsCounter(),
this::onDownloadMapsOptionSelected
));
items.add(new MenuBottomSheetItem(R.string.settings, R.drawable.ic_settings, this::onSettingsOptionSelected));
items.add(new MenuBottomSheetItem(R.string.share_my_location, R.drawable.ic_share, this::onShareLocationOptionSelected));
return items;
}
@Override
public void onNoConnectionError()
{
@ -535,9 +552,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
private void initMap(boolean isLaunchByDeepLink)
{
mFadeView = findViewById(R.id.fade_view);
mFadeView.setListener(this::onFadeViewTouch);
mMapFragment = (MapFragment) getSupportFragmentManager().findFragmentByTag(MapFragment.class.getName());
if (mMapFragment == null)
{
@ -557,12 +571,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
}
private boolean onFadeViewTouch()
{
closeMenu();
return getCurrentMenu().close(true);
}
public boolean isMapAttached()
{
return mMapFragment != null && mMapFragment.isAdded();
@ -581,20 +589,44 @@ public class MwmActivity extends BaseMwmFragmentActivity
View myPosition = frame.findViewById(R.id.my_position);
mNavMyPosition = new MyPositionButton(myPosition, mOnMyPositionClickListener);
initToggleMapLayerController(frame);
View mLayersButton = frame.findViewById(R.id.layers_button);
mToggleMapLayerController = new MapLayerCompositeController(mLayersButton, this::toggleMapLayerMenu,this);
mNavAnimationController = new NavigationButtonsAnimationController(
zoomIn, zoomOut, myPosition, getWindow().getDecorView().getRootView(), this);
}
private void initToggleMapLayerController(@NonNull View frame)
private void toggleMapLayerMenu()
{
ImageButton trafficBtn = frame.findViewById(R.id.traffic);
TrafficButton traffic = new TrafficButton(trafficBtn);
View subway = frame.findViewById(R.id.subway);
View isoLines = frame.findViewById(R.id.isolines);
mToggleMapLayerController = new MapLayerCompositeController(traffic, subway, isoLines, this);
mToggleMapLayerController.attachCore();
if (!closeMapLayerMenu())
showMapLayerMenu();
}
private boolean closeMapLayerMenu()
{
if (!mLayersBottomSheet.isAdded())
return false;
mLayersBottomSheet.dismiss();
return true;
}
private void showMapLayerMenu()
{
mLayersBottomSheet.show(getSupportFragmentManager(), "layersBottomSheet");
}
private boolean closeMainMenu()
{
if (!mMainMenuBottomSheet.isAdded())
return false;
mMainMenuBottomSheet.dismiss();
return true;
}
private void showMainMenu()
{
mMainMenuBottomSheet = new MenuBottomSheetFragment(mToggleMapLayerFragment, getMainMenuItems());
mMainMenuBottomSheet.show(getSupportFragmentManager(), "mainMenuBottomSheet");
}
/**
@ -619,8 +651,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (removeCurrentFragment(true))
{
InputUtils.hideKeyboard(mFadeView);
mFadeView.fadeOut();
return true;
}
@ -633,37 +663,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
return;
closePlacePage();
if (removeCurrentFragment(true))
{
InputUtils.hideKeyboard(mFadeView);
mFadeView.fadeOut();
}
}
/**
* @return False if the menu was already closed, true otherwise
*/
public boolean closeMenu()
{
if (!getMainMenuController().isClosed())
{
mFadeView.fadeOut();
getMainMenuController().close();
return true;
}
return false;
}
/**
* Tries to close the main menu then runs the given runnable
*
* @param procAfterClose The runnable to run after closing the menu
*/
public void closeMenu(@Nullable Runnable procAfterClose)
{
closeMenu();
if (procAfterClose != null)
procAfterClose.run();
removeCurrentFragment(true);
}
/**
@ -712,9 +712,10 @@ public class MwmActivity extends BaseMwmFragmentActivity
closeFloatingToolbars(clearSearchText, true);
}
private void closeFloatingPanels()
public void closeFloatingPanels()
{
closeMenu();
closeMainMenu();
closeMapLayerMenu();
closePlacePage();
}
@ -726,24 +727,15 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void startLocationToPoint(final @Nullable MapObject endPoint)
{
closeMenu(() -> {
if (!PermissionsUtils.isFineLocationGranted(MwmActivity.this))
PermissionsUtils.requestLocationPermission(MwmActivity.this, REQ_CODE_LOCATION_PERMISSION);
closeFloatingPanels();
if (!PermissionsUtils.isFineLocationGranted(MwmActivity.this))
PermissionsUtils.requestLocationPermission(MwmActivity.this, REQ_CODE_LOCATION_PERMISSION);
MapObject startPoint = LocationHelper.INSTANCE.getMyPosition();
RoutingController.get().prepare(startPoint, endPoint);
MapObject startPoint = LocationHelper.INSTANCE.getMyPosition();
RoutingController.get().prepare(startPoint, endPoint);
// TODO: check for tablet.
closePlacePage();
});
}
public void refreshFade()
{
if (getCurrentMenu().isOpen() || !mMainMenuController.isClosed())
mFadeView.fadeIn();
else
mFadeView.fadeOut();
// TODO: check for tablet.
closePlacePage();
}
private void initMainMenu()
@ -883,24 +875,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
myPositionClick();
}
@Override
public void onSubwayLayerSelected()
{
toggleLayer(Mode.SUBWAY);
}
@Override
public void onTrafficLayerSelected()
{
toggleLayer(Mode.TRAFFIC);
}
@Override
public void onIsolinesLayerSelected()
{
toggleLayer(Mode.ISOLINES);
}
private void onIsolinesStateChanged(@NonNull IsolinesState type)
{
if (type != IsolinesState.EXPIREDDATA)
@ -997,7 +971,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (mNavAnimationController != null)
mNavAnimationController.onResume();
mPlacePageController.onActivityResumed(this);
refreshFade();
}
@Override
@ -1066,20 +1039,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
mToggleMapLayerController.detachCore();
TrafficManager.INSTANCE.detachAll();
mPlacePageController.destroy();
getMainMenuController().destroy();
}
@Override
public void onBackPressed()
{
if (getCurrentMenu().close(true))
{
mFadeView.fadeOut();
return;
}
RoutingController routingController = RoutingController.get();
if (!closeMenu() && !closePlacePage() && !closeSearchToolbar(true, true) &&
if (!closeMainMenu() && !closeMapLayerMenu() && !closePlacePage() && !closeSearchToolbar(true, true) &&
!closeSidePanel() && !closePositionChooser() &&
!routingController.resetToPlanningStateIfNavigating() && !routingController.cancel())
{
@ -1173,9 +1139,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
setFullscreen(false);
mPlacePageController.openFor(data);
if (UiUtils.isVisible(mFadeView))
mFadeView.fadeOut();
}
// Called from JNI.
@ -1613,7 +1576,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
// TODO:
// mPlacePage.refreshViews();
mNavigationController.show(show);
refreshFade();
if (mOnmapDownloader != null)
mOnmapDownloader.updateState(false);
}
@ -1883,7 +1845,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public void onRoutingStart()
{
closeMenu(() -> RoutingController.get().start());
closeFloatingPanels();
RoutingController.get().start();
}
@Override
@ -1981,12 +1944,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
mToggleMapLayerController.toggleMode(mode);
}
@NonNull
private MenuController getMainMenuController()
{
return mMainMenuController;
}
public void showTrackOnMap(long trackId)
{
Track track = BookmarkManager.INSTANCE.getTrack(trackId);
@ -2067,11 +2024,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
getActivity().closePlacePage();
getActivity().closeSidePanel();
MenuController controller = getActivity().getMainMenuController();
if (controller.isClosed())
controller.open();
else
controller.close();
getActivity().showMainMenu();
}
}
@ -2086,7 +2039,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void onMenuItemClickInternal()
{
RoutingController.get().cancel();
getActivity().closeMenu(() -> getActivity().showSearch(getActivity().mSearchController.getQuery()));
getActivity().closeFloatingPanels();
getActivity().showSearch(getActivity().mSearchController.getQuery());
}
}
@ -2100,7 +2054,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
void onMenuItemClickInternal()
{
getActivity().closeMenu(getActivity()::showBookmarks);
getActivity().closeFloatingPanels();
getActivity().showBookmarks();
}
}
@ -2133,73 +2088,41 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
}
private class MainMenuStateObserver implements MenuStateObserver
public void onAddPlaceOptionSelected()
{
@Override
public void onMenuOpen()
{
mFadeView.fadeIn();
}
@Override
public void onMenuClosed()
{
mFadeView.fadeOut();
getCurrentMenu().updateMarker();
}
closeFloatingPanels();
showPositionChooser(false, false);
}
private class MainMenuOptionSelectedListener implements MainMenuOptionListener
public void onDownloadMapsOptionSelected()
{
@Override
public void onAddPlaceOptionSelected()
{
closeMenu(() -> showPositionChooser(false, false));
}
RoutingController.get().cancel();
closeFloatingPanels();
showDownloader(false);
}
@Override
public void onDownloadMapsOptionSelected()
{
RoutingController.get().cancel();
closeMenu(() -> showDownloader(false));
}
public void onSettingsOptionSelected()
{
Intent intent = new Intent(getActivity(), SettingsActivity.class);
closeFloatingPanels();
getActivity().startActivity(intent);
}
@Override
public void onSettingsOptionSelected()
{
Intent intent = new Intent(getActivity(), SettingsActivity.class);
closeMenu(() -> getActivity().startActivity(intent));
}
public void onShareLocationOptionSelected()
{
closeFloatingPanels();
shareMyLocation();
}
@Override
public void onShareLocationOptionSelected()
{
closeMenu(MwmActivity.this::shareMyLocation);
}
public void onSubwayLayerOptionSelected()
{
closeFloatingPanels();
toggleLayer(Mode.SUBWAY);
}
@Override
public void onReportOptionSelected()
{
closeMenu(() -> Utils.sendFeedback(getActivity()));
}
@Override
public void onSubwayLayerOptionSelected()
{
toggleLayer(Mode.SUBWAY);
}
@Override
public void onTrafficLayerOptionSelected()
{
toggleLayer(Mode.TRAFFIC);
}
@Override
public void onIsolinesLayerOptionSelected()
{
toggleLayer(Mode.ISOLINES);
}
public void onIsolinesLayerOptionSelected()
{
closeFloatingPanels();
toggleLayer(Mode.ISOLINES);
}
}

View file

@ -1,15 +1,13 @@
package com.mapswithme.maps.maplayer;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.mapswithme.maps.maplayer.subway.DefaultMapLayerController;
import com.mapswithme.maps.maplayer.traffic.widget.TrafficButton;
import com.mapswithme.maps.maplayer.traffic.widget.TrafficButtonController;
import com.mapswithme.util.InputUtils;
import com.mapswithme.util.UiUtils;
import java.util.ArrayList;
import java.util.List;
@ -19,49 +17,25 @@ public class MapLayerCompositeController implements MapLayerController
@NonNull
private final AppCompatActivity mActivity;
@NonNull
private final List<ControllerAndMode> mLayers;
private final List<Mode> mLayers;
@NonNull
private ControllerAndMode mCurrentLayer;
private Mode mCurrentLayer;
@NonNull
private final OpenBottomDialogClickListener mOpenBottomDialogClickListener;
private final View mLayersButton;
@NonNull
OnShowMenuListener mOnshowMenuListener;
public MapLayerCompositeController(@NonNull TrafficButton traffic, @NonNull View subway,
@NonNull View isoLines, @NonNull AppCompatActivity activity)
public MapLayerCompositeController(@NonNull View layersButton, @NonNull OnShowMenuListener onshowMenuListener, @NonNull AppCompatActivity activity)
{
mOpenBottomDialogClickListener = new OpenBottomDialogClickListener(activity);
mActivity = activity;
mLayers = createLayers(traffic, subway, isoLines, activity, mOpenBottomDialogClickListener);
mLayersButton = layersButton;
mLayersButton.setOnClickListener(view -> onLayersButtonClick());
mOnshowMenuListener = onshowMenuListener;
mLayers = new ArrayList<>();
mLayers.add(Mode.SUBWAY);
mLayers.add(Mode.ISOLINES);
mCurrentLayer = getCurrentLayer();
toggleMode(mCurrentLayer.getMode());
}
@NonNull
private static List<ControllerAndMode> createLayers(@NonNull TrafficButton traffic,
@NonNull View subway,
@NonNull View isoLinesView,
@NonNull AppCompatActivity activity,
@NonNull View.OnClickListener dialogClickListener)
{
traffic.setOnclickListener(dialogClickListener);
TrafficButtonController trafficButtonController = new TrafficButtonController(traffic,
activity);
subway.setOnClickListener(dialogClickListener);
DefaultMapLayerController subwayMapLayerController = new DefaultMapLayerController(subway);
isoLinesView.setOnClickListener(dialogClickListener);
DefaultMapLayerController isoLinesController = new DefaultMapLayerController(isoLinesView);
ControllerAndMode subwayEntry = new ControllerAndMode(Mode.SUBWAY, subwayMapLayerController);
ControllerAndMode trafficEntry = new ControllerAndMode(Mode.TRAFFIC, trafficButtonController);
ControllerAndMode isoLineEntry = new ControllerAndMode(Mode.ISOLINES, isoLinesController);
List<ControllerAndMode> entries = new ArrayList<>();
entries.add(subwayEntry);
entries.add(isoLineEntry);
entries.add(trafficEntry);
return entries;
toggleMode(mCurrentLayer);
}
public void toggleMode(@NonNull Mode mode)
@ -88,209 +62,129 @@ public class MapLayerCompositeController implements MapLayerController
private void turnInitialMode()
{
mCurrentLayer.getController().hideImmediately();
UiUtils.hide(mLayersButton);
mCurrentLayer = mLayers.iterator().next();
mCurrentLayer.getController().showImmediately();
UiUtils.show(mLayersButton);
}
public void applyLastActiveMode()
{
toggleMode(mCurrentLayer.getMode(), true);
toggleMode(mCurrentLayer, true);
}
@Override
public void attachCore()
{
for (ControllerAndMode each : mLayers)
{
each.getController().attachCore();
}
// Do nothing
}
@Override
public void detachCore()
{
for (ControllerAndMode each : mLayers)
{
each.getController().detachCore();
}
// Do nothing
}
private void setMasterController(@NonNull Mode mode)
{
for (ControllerAndMode each : mLayers)
for (Mode each : mLayers)
{
if (each.getMode() == mode)
if (each == mode)
{
mCurrentLayer = each;
}
else
{
each.getController().hideImmediately();
each.getMode().setEnabled(mActivity, false);
UiUtils.hide(mLayersButton);
each.setEnabled(mActivity, false);
}
}
}
private void showMasterController(boolean animate)
{
if (animate)
mCurrentLayer.getController().show();
else
mCurrentLayer.getController().showImmediately();
UiUtils.show(mLayersButton);
}
@NonNull
private ControllerAndMode getCurrentLayer()
private Mode getCurrentLayer()
{
for (ControllerAndMode each : mLayers)
for (Mode each : mLayers)
{
if (each.getMode().isEnabled(mActivity))
if (each.isEnabled(mActivity))
return each;
}
return mLayers.iterator().next();
}
@Override
public void turnOn()
{
mCurrentLayer.getController().turnOn();
mCurrentLayer.getMode().setEnabled(mActivity, true);
mLayersButton.setSelected(true);
mCurrentLayer.setEnabled(mActivity, true);
}
@Override
public void turnOff()
{
mCurrentLayer.getController().turnOff();
mCurrentLayer.getMode().setEnabled(mActivity, false);
mLayersButton.setSelected(false);
mCurrentLayer.setEnabled(mActivity, false);
}
@Override
public void show()
{
mCurrentLayer.getController().show();
UiUtils.show(mLayersButton);
}
@Override
public void showImmediately()
{
mCurrentLayer.getController().showImmediately();
UiUtils.show(mLayersButton);
}
@Override
public void hide()
{
mCurrentLayer.getController().hide();
UiUtils.hide(mLayersButton);
}
@Override
public void hideImmediately()
{
mCurrentLayer.getController().hideImmediately();
UiUtils.hide(mLayersButton);
}
@Override
public void adjust(int offsetX, int offsetY)
{
for(ControllerAndMode controllerAndMode: mLayers)
controllerAndMode.getController().adjust(offsetX, offsetY);
}
private void showDialog()
{
ToggleMapLayerDialog.show(mActivity);
}
@NonNull
private ControllerAndMode findModeMapLayerController(@NonNull Mode mode)
{
for (ControllerAndMode each : mLayers)
{
if (each.getMode() == mode)
return each;
}
throw new IllegalArgumentException("Mode not found : " + mode);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLayersButton.getLayoutParams();
params.setMargins(offsetX, offsetY, 0, 0);
mLayersButton.setLayoutParams(params);
}
public void turnOnView(@NonNull Mode mode)
{
setMasterController(mode);
mCurrentLayer.getController().showImmediately();
mCurrentLayer.getController().turnOn();
UiUtils.show(mLayersButton);
mLayersButton.setSelected(true);
}
public void turnOffCurrentView()
private void onLayersButtonClick()
{
mCurrentLayer.getController().turnOff();
}
private static class ControllerAndMode
{
@NonNull
private final Mode mMode;
@NonNull
private final MapLayerController mController;
ControllerAndMode(@NonNull Mode mode, @NonNull MapLayerController controller)
if (mCurrentLayer.isEnabled(mActivity))
{
mMode = mode;
mController = controller;
}
@Override
public boolean equals(Object o)
Mode mode = getCurrentLayer();
turnOff();
toggleMode(mode);
} else
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ControllerAndMode that = (ControllerAndMode) o;
return mMode == that.getMode();
}
@Override
public int hashCode()
{
return mMode.hashCode();
}
@NonNull
MapLayerController getController()
{
return mController;
}
@NonNull
Mode getMode()
{
return mMode;
InputUtils.hideKeyboard(mActivity.getWindow().getDecorView());
mOnshowMenuListener.onShow();
}
}
private class OpenBottomDialogClickListener implements View.OnClickListener
public interface OnShowMenuListener
{
@NonNull
private final Activity mActivity;
OpenBottomDialogClickListener(@NonNull Activity activity)
{
mActivity = activity;
}
@Override
public final void onClick(View v)
{
if (mCurrentLayer.getMode().isEnabled(mActivity))
{
Mode mode = getCurrentLayer().getMode();
turnOff();
toggleMode(mode);
}
else
{
InputUtils.hideKeyboard(mActivity.getWindow().getDecorView());
showDialog();
}
}
void onShow();
}
}

View file

@ -1,6 +0,0 @@
package com.mapswithme.maps.maplayer;
public interface OnIsolinesLayerToggleListener
{
void onIsolinesLayerSelected();
}

View file

@ -1,156 +0,0 @@
package com.mapswithme.maps.maplayer;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.mapswithme.maps.R;
import com.mapswithme.maps.maplayer.subway.OnSubwayLayerToggleListener;
import com.mapswithme.maps.maplayer.traffic.OnTrafficLayerToggleListener;
import com.mapswithme.maps.widget.recycler.SpanningLinearLayoutManager;
import java.util.Objects;
public class ToggleMapLayerDialog extends DialogFragment
{
@NonNull
@SuppressWarnings("NullableProblems")
private LayersAdapter mAdapter;
@SuppressWarnings("NullableProblems")
@NonNull
private View mRoot;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
BottomSheetDialog dialog = new BottomSheetDialog(requireActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
mRoot = inflater.inflate(R.layout.fragment_toggle_map_layer, null, false);
dialog.setOnShowListener(this::onShow);
dialog.setContentView(mRoot);
initChildren(mRoot);
return dialog;
}
private void onShow(@NonNull DialogInterface dialogInterface)
{
BottomSheetDialog dialog = (BottomSheetDialog) dialogInterface;
View bottomSheet = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(Objects.requireNonNull(bottomSheet));
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
private void initChildren(@NonNull View root)
{
initCloseBtn(root);
initRecycler(root);
}
private void initCloseBtn(@NonNull View root)
{
View closeBtn = root.findViewById(R.id.сlose_btn);
closeBtn.setOnClickListener(v -> dismiss());
}
private void initRecycler(@NonNull View root)
{
RecyclerView recycler = root.findViewById(R.id.recycler);
RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(requireContext(),
LinearLayoutManager.HORIZONTAL,
false);
recycler.setLayoutManager(layoutManager);
mAdapter = new LayersAdapter();
mAdapter.setLayerModes(LayersUtils.createItems(requireContext(),
new SubwayItemClickListener(),
new TrafficItemClickListener(),
new IsolinesItemClickListener()));
recycler.setAdapter(mAdapter);
}
public static void show(@NonNull AppCompatActivity activity)
{
ToggleMapLayerDialog frag = new ToggleMapLayerDialog();
String tag = frag.getClass().getCanonicalName();
FragmentManager fm = activity.getSupportFragmentManager();
Fragment oldInstance = fm.findFragmentByTag(tag);
if (oldInstance != null)
return;
fm.beginTransaction().add(frag, tag).commitAllowingStateLoss();
fm.executePendingTransactions();
}
@NonNull
public View getRootView()
{
return mRoot;
}
@Nullable
public static ToggleMapLayerDialog getInstance(@NonNull AppCompatActivity activity) {
String tag = ToggleMapLayerDialog.class.getCanonicalName();
return (ToggleMapLayerDialog) activity.getSupportFragmentManager().findFragmentByTag(tag);
}
private class SubwayItemClickListener extends DefaultClickListener
{
private SubwayItemClickListener()
{
super(mAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
OnSubwayLayerToggleListener listener = (OnSubwayLayerToggleListener) requireActivity();
listener.onSubwayLayerSelected();
}
}
private class TrafficItemClickListener extends DefaultClickListener
{
private TrafficItemClickListener()
{
super(mAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
OnTrafficLayerToggleListener listener = (OnTrafficLayerToggleListener) requireActivity();
listener.onTrafficLayerSelected();
}
}
private class IsolinesItemClickListener extends AbstractIsoLinesClickListener
{
private IsolinesItemClickListener()
{
super(mAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
super.onItemClickInternal(v,item);
OnIsolinesLayerToggleListener listener = (OnIsolinesLayerToggleListener) requireActivity();
listener.onIsolinesLayerSelected();
}
}
}

View file

@ -0,0 +1,102 @@
package com.mapswithme.maps.maplayer;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.widget.recycler.SpanningLinearLayoutManager;
public class ToggleMapLayerFragment extends Fragment
{
@NonNull
private final LayerItemClickListener mIsolinesListener;
@NonNull
private final LayerItemClickListener mSubwayListener;
@NonNull
private LayersAdapter mAdapter;
public ToggleMapLayerFragment(@NonNull LayerItemClickListener isolinesListener, @NonNull LayerItemClickListener subwayListener)
{
this.mIsolinesListener = isolinesListener;
this.mSubwayListener = subwayListener;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
View mRoot = inflater.inflate(R.layout.fragment_toggle_map_layer, container, false);
initRecycler(mRoot);
return mRoot;
}
private void initRecycler(@NonNull View root)
{
RecyclerView recycler = root.findViewById(R.id.recycler);
RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(requireContext(),
LinearLayoutManager.HORIZONTAL,
false);
recycler.setLayoutManager(layoutManager);
mAdapter = new LayersAdapter();
mAdapter.setLayerModes(LayersUtils.createItems(requireContext(),
new SubwayItemClickListener(),
new TrafficItemClickListener(),
new IsolinesItemClickListener()));
recycler.setAdapter(mAdapter);
recycler.setNestedScrollingEnabled(false);
}
public interface LayerItemClickListener
{
void onClick();
}
private class SubwayItemClickListener extends DefaultClickListener
{
private SubwayItemClickListener()
{
super(mAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
mSubwayListener.onClick();
}
}
private class TrafficItemClickListener extends DefaultClickListener
{
private TrafficItemClickListener()
{
super(mAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{}
}
private class IsolinesItemClickListener extends AbstractIsoLinesClickListener
{
private IsolinesItemClickListener()
{
super(mAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
super.onItemClickInternal(v, item);
mIsolinesListener.onClick();
}
}
}

View file

@ -1,77 +0,0 @@
package com.mapswithme.maps.maplayer.subway;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import com.mapswithme.maps.maplayer.MapLayerController;
import com.mapswithme.util.UiUtils;
public class DefaultMapLayerController implements MapLayerController
{
@NonNull
private final View mLayerView;
public DefaultMapLayerController(@NonNull View subwayBtn)
{
mLayerView = subwayBtn;
UiUtils.addStatusBarOffset(mLayerView);
}
@Override
public void turnOn()
{
mLayerView.setSelected(true);
}
@Override
public void turnOff()
{
mLayerView.setSelected(false);
}
@Override
public void show()
{
UiUtils.show(mLayerView);
}
@Override
public void showImmediately()
{
UiUtils.show(mLayerView);
}
@Override
public void hide()
{
UiUtils.hide(mLayerView);
}
@Override
public void hideImmediately()
{
UiUtils.hide(mLayerView);
}
@Override
public void adjust(int offsetX, int offsetY)
{
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mLayerView.getLayoutParams();
params.setMargins(offsetX, offsetY, 0, 0);
mLayerView.setLayoutParams(params);
}
@Override
public void attachCore()
{
/* Do nothing by default */
}
@Override
public void detachCore()
{
/* Do nothing by default */
}
}

View file

@ -1,6 +0,0 @@
package com.mapswithme.maps.maplayer.subway;
public interface OnSubwayLayerToggleListener
{
void onSubwayLayerSelected();
}

View file

@ -1,6 +0,0 @@
package com.mapswithme.maps.maplayer.traffic;
public interface OnTrafficLayerToggleListener
{
void onTrafficLayerSelected();
}

View file

@ -179,7 +179,8 @@ public class NavigationController implements Application.ActivityLifecycleCallba
stop(parent);
break;
case SETTINGS:
parent.closeMenu(() -> parent.startActivity(new Intent(parent, SettingsActivity.class)));
parent.closeFloatingPanels();
parent.startActivity(new Intent(parent, SettingsActivity.class));
break;
case TTS_VOLUME:
TtsPlayer.setEnabled(!TtsPlayer.isEnabled());
@ -192,13 +193,11 @@ public class NavigationController implements Application.ActivityLifecycleCallba
// break;
case TOGGLE:
mNavMenu.toggle(true);
parent.refreshFade();
}
}
public void stop(MwmActivity parent)
{
parent.refreshFade();
mSearchWheel.reset();
if (mBound)

View file

@ -1,110 +0,0 @@
package com.mapswithme.maps.widget.menu;
import android.annotation.SuppressLint;
import android.view.View;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.GestureDetectorCompat;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import java.util.Objects;
public class BottomSheetMenuController implements MenuController
{
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
private static final String TAG = BottomSheetMenuController.class.getSimpleName();
@SuppressWarnings("NullableProblems")
@NonNull
private BottomSheetBehavior<View> mSheetBehavior;
@IdRes
private final int mSheetResId;
@NonNull
private final MenuRenderer mMenuRenderer;
@Nullable
private final MenuStateObserver mStateObserver;
private final BottomSheetBehavior.BottomSheetCallback mSheetCallback
= new BottomSheetBehavior.BottomSheetCallback()
{
@Override
public void onStateChanged(@NonNull View view, int state)
{
LOGGER.d(TAG, "State change, new = " + BottomSheetMenuUtils.toString(state));
if (BottomSheetMenuUtils.isSettlingState(state) || BottomSheetMenuUtils.isDraggingState(state))
return;
if (BottomSheetMenuUtils.isHiddenState(state))
{
mMenuRenderer.onHide();
if (mStateObserver != null)
mStateObserver.onMenuClosed();
return;
}
if (mStateObserver != null)
mStateObserver.onMenuOpen();
}
@Override
public void onSlide(@NonNull View view, float v)
{
// Do nothing by default.
}
};
BottomSheetMenuController(int sheetResId, @NonNull MenuRenderer menuRenderer,
@Nullable MenuStateObserver stateObserver)
{
mSheetResId = sheetResId;
mMenuRenderer = menuRenderer;
mStateObserver = stateObserver;
}
@Override
public void open()
{
mMenuRenderer.render();
mSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
@Override
public void close()
{
mSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
@Override
public boolean isClosed()
{
int state = mSheetBehavior.getState();
return BottomSheetMenuUtils.isHiddenState(state)
|| (mSheetBehavior.getSkipCollapsed() && BottomSheetMenuUtils.isCollapsedState(state));
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void initialize(@Nullable View view)
{
Objects.requireNonNull(view);
View sheet = view.findViewById(mSheetResId);
Objects.requireNonNull(sheet);
mSheetBehavior = BottomSheetBehavior.from(sheet);
mSheetBehavior.addBottomSheetCallback(mSheetCallback);
mSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
GestureDetectorCompat gestureDetector = new GestureDetectorCompat(
view.getContext(), new BottomSheetMenuGestureListener(mSheetBehavior));
sheet.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event));
mMenuRenderer.initialize(sheet);
}
@Override
public void destroy()
{
mSheetBehavior.removeBottomSheetCallback(mSheetCallback);
mMenuRenderer.destroy();
}
}

View file

@ -1,36 +0,0 @@
package com.mapswithme.maps.widget.menu;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.trafi.anchorbottomsheetbehavior.AnchorBottomSheetBehavior;
public class BottomSheetMenuGestureListener extends GestureDetector.SimpleOnGestureListener
{
@NonNull
private final BottomSheetBehavior<View> mBottomSheetBehavior;
public BottomSheetMenuGestureListener(@NonNull BottomSheetBehavior<View> bottomSheetBehavior)
{
mBottomSheetBehavior = bottomSheetBehavior;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e)
{
@AnchorBottomSheetBehavior.State
int state = mBottomSheetBehavior.getState();
if (!BottomSheetMenuUtils.isHiddenState(state) && !BottomSheetMenuUtils.isDraggingState(state)
&& !BottomSheetMenuUtils.isSettlingState(state))
{
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
return true;
}
return false;
}
}

View file

@ -1,53 +0,0 @@
package com.mapswithme.maps.widget.menu;
import androidx.annotation.NonNull;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
class BottomSheetMenuUtils
{
static boolean isSettlingState(int state)
{
return state == BottomSheetBehavior.STATE_SETTLING;
}
static boolean isDraggingState(int state)
{
return state == BottomSheetBehavior.STATE_DRAGGING;
}
static boolean isCollapsedState(int state)
{
return state == BottomSheetBehavior.STATE_COLLAPSED;
}
static boolean isExpandedState(int state)
{
return state == BottomSheetBehavior.STATE_EXPANDED;
}
static boolean isHiddenState(int state)
{
return state == BottomSheetBehavior.STATE_HIDDEN;
}
@NonNull
static String toString(int state)
{
switch (state)
{
case BottomSheetBehavior.STATE_EXPANDED:
return "EXPANDED";
case BottomSheetBehavior.STATE_COLLAPSED:
return "COLLAPSED";
case BottomSheetBehavior.STATE_DRAGGING:
return "DRAGGING";
case BottomSheetBehavior.STATE_SETTLING:
return "SETTLING";
case BottomSheetBehavior.STATE_HIDDEN:
return "HIDDEN";
default:
throw new AssertionError("Unsupported state detected: " + state);
}
}
}

View file

@ -1,13 +0,0 @@
package com.mapswithme.maps.widget.menu;
public interface MainMenuOptionListener
{
void onAddPlaceOptionSelected();
void onDownloadMapsOptionSelected();
void onSettingsOptionSelected();
void onShareLocationOptionSelected();
void onReportOptionSelected();
void onSubwayLayerOptionSelected();
void onTrafficLayerOptionSelected();
void onIsolinesLayerOptionSelected();
}

View file

@ -1,157 +0,0 @@
package com.mapswithme.maps.widget.menu;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.NoConnectionListener;
import com.mapswithme.maps.downloader.MapManager;
import com.mapswithme.maps.downloader.UpdateInfo;
import com.mapswithme.maps.maplayer.AbstractIsoLinesClickListener;
import com.mapswithme.maps.maplayer.BottomSheetItem;
import com.mapswithme.maps.maplayer.DefaultClickListener;
import com.mapswithme.maps.maplayer.LayersAdapter;
import com.mapswithme.maps.maplayer.LayersUtils;
import com.mapswithme.maps.widget.recycler.SpanningLinearLayoutManager;
import com.mapswithme.util.Graphics;
import com.mapswithme.util.UiUtils;
import java.util.Objects;
public class MainMenuRenderer implements MenuRenderer
{
@NonNull
private final MainMenuOptionListener mListener;
@NonNull
@SuppressWarnings("NullableProblems")
private LayersAdapter mLayersAdapter;
@SuppressWarnings("NullableProblems")
@NonNull
private TextView mDownloadMapsCounter;
@SuppressWarnings("NullableProblems")
@NonNull
private NestedScrollView mScrollView;
@NonNull
private final NoConnectionListener mNoConnectionListener;
MainMenuRenderer(@NonNull MainMenuOptionListener listener,
@NonNull NoConnectionListener noConnectionListener)
{
mListener = listener;
mNoConnectionListener = noConnectionListener;
}
@Override
public void render()
{
mLayersAdapter.notifyDataSetChanged();
renderDownloadMapsCounter();
}
private void renderDownloadMapsCounter()
{
UpdateInfo info = MapManager.nativeGetUpdateInfo(null);
int count = info == null ? 0 : info.filesCount;
UiUtils.showIf(count > 0, mDownloadMapsCounter);
if (count > 0)
mDownloadMapsCounter.setText(String.valueOf(count));
}
@Override
public void initialize(@Nullable View view)
{
Objects.requireNonNull(view);
mScrollView = (NestedScrollView) view;
initLayersRecycler(view);
TextView addPlace = view.findViewById(R.id.add_place);
addPlace.setOnClickListener(v -> mListener.onAddPlaceOptionSelected());
Graphics.tint(addPlace);
View downloadMapsContainer = view.findViewById(R.id.download_maps_container);
downloadMapsContainer.setOnClickListener(v -> mListener.onDownloadMapsOptionSelected());
TextView downloadMaps = downloadMapsContainer.findViewById(R.id.download_maps);
Graphics.tint(downloadMaps);
mDownloadMapsCounter = downloadMapsContainer.findViewById(R.id.counter);
TextView settings = view.findViewById(R.id.settings);
settings.setOnClickListener(v -> mListener.onSettingsOptionSelected());
Graphics.tint(settings);
TextView share = view.findViewById(R.id.share);
share.setOnClickListener(v -> mListener.onShareLocationOptionSelected());
Graphics.tint(share);
}
private void initLayersRecycler(@NonNull View view)
{
RecyclerView layersRecycler = view.findViewById(R.id.layers_recycler);
RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(layersRecycler.getContext(),
LinearLayoutManager.HORIZONTAL,
false);
layersRecycler.setLayoutManager(layoutManager);
mLayersAdapter = new LayersAdapter();
mLayersAdapter.setLayerModes(LayersUtils.createItems(layersRecycler.getContext(),
new SubwayItemClickListener(),
new TrafficItemClickListener(),
new IsolinesItemClickListener()));
layersRecycler.setAdapter(mLayersAdapter);
}
@Override
public void destroy()
{
// Do nothing by default.
}
@Override
public void onHide()
{
mScrollView.scrollTo(0, 0);
}
private class SubwayItemClickListener extends DefaultClickListener
{
SubwayItemClickListener()
{
super(mLayersAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
mListener.onSubwayLayerOptionSelected();
}
}
private class TrafficItemClickListener extends DefaultClickListener
{
TrafficItemClickListener()
{
super(mLayersAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
mListener.onTrafficLayerOptionSelected();
}
}
private class IsolinesItemClickListener extends AbstractIsoLinesClickListener
{
IsolinesItemClickListener()
{
super(mLayersAdapter);
}
@Override
public void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
super.onItemClickInternal(v, item);
mListener.onIsolinesLayerOptionSelected();
}
}
}

View file

@ -1,12 +0,0 @@
package com.mapswithme.maps.widget.menu;
import android.view.View;
import com.mapswithme.maps.base.Initializable;
public interface MenuController extends Initializable<View>
{
void open();
void close();
boolean isClosed();
}

View file

@ -1,20 +0,0 @@
package com.mapswithme.maps.widget.menu;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.NoConnectionListener;
public class MenuControllerFactory
{
@NonNull
public static MenuController createMainMenuController(@Nullable MenuStateObserver stateObserver,
@NonNull MainMenuOptionListener listener,
@NonNull NoConnectionListener noConnectionListener)
{
return new BottomSheetMenuController(R.id.main_menu_sheet, new MainMenuRenderer(listener,
noConnectionListener),
stateObserver);
}
}

View file

@ -1,11 +0,0 @@
package com.mapswithme.maps.widget.menu;
import android.view.View;
import com.mapswithme.maps.base.Hideable;
import com.mapswithme.maps.base.Initializable;
public interface MenuRenderer extends Initializable<View>, Hideable
{
void render();
}

View file

@ -1,7 +0,0 @@
package com.mapswithme.maps.widget.menu;
public interface MenuStateObserver
{
void onMenuOpen();
void onMenuClosed();
}

View file

@ -8,6 +8,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -22,20 +23,38 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment
{
@Nullable
private final String title;
@Nullable
private final Fragment headerFragment;
private final ArrayList<MenuBottomSheetItem> menuBottomSheetItems;
public MenuBottomSheetFragment(@NonNull Fragment headerFragment, ArrayList<MenuBottomSheetItem> menuBottomSheetItems)
{
this.title = null;
this.headerFragment = headerFragment;
this.menuBottomSheetItems = menuBottomSheetItems;
}
public MenuBottomSheetFragment(@NonNull String title, ArrayList<MenuBottomSheetItem> menuBottomSheetItems)
{
this.title = title;
this.headerFragment = null;
this.menuBottomSheetItems = menuBottomSheetItems;
}
public MenuBottomSheetFragment(ArrayList<MenuBottomSheetItem> menuBottomSheetItems)
{
this.title = null;
this.headerFragment = null;
this.menuBottomSheetItems = menuBottomSheetItems;
}
public MenuBottomSheetFragment(@NonNull Fragment headerFragment)
{
this.title = null;
this.headerFragment = headerFragment;
this.menuBottomSheetItems = new ArrayList<>();
}
@Override
public int getTheme()
{
@ -84,5 +103,7 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment
MenuAdapter menuAdapter = new MenuAdapter(menuBottomSheetItems, this::dismiss);
recyclerView.setAdapter(menuAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
if (headerFragment != null)
getChildFragmentManager().beginTransaction().add(R.id.bottom_sheet_menu_header, headerFragment).commit();
}
}