[android] Use new Menu Bottom Sheet component

Signed-off-by: Arnaud Vergnet <arnaud.vergnet@mailo.com>
This commit is contained in:
Arnaud Vergnet 2022-03-12 19:57:54 +01:00 committed by Viktor Govako
parent be9729341b
commit 490ade8b8d
31 changed files with 583 additions and 543 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

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="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

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="M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z"/>
</vector>

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.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
</vector>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/bottomSheetTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_base"
android:layout_marginStart="@dimen/margin_base"
android:text="Title"
style="@style/MwmTextAppearance.Title"
android:textSize="20sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/bottomSheetMenuContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottom_sheet_menu_item"
android:layout_width="match_parent"
android:layout_height="@dimen/menu_list_item_height"
android:paddingLeft="@dimen/margin_base"
android:paddingRight="@dimen/margin_base"
android:gravity="center_vertical"
android:background="?clickableBackground"
android:orientation="horizontal">
<ImageView
android:id="@+id/bottom_sheet_menu_item_icon"
android:layout_width="@dimen/bookmark_icon_size"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
tools:src="@drawable/ic_menu_download"
app:tint="?android:textColorSecondary"/>
<TextView
android:id="@+id/bottom_sheet_menu_item_text"
style="@style/MwmTextAppearance.Body1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
android:gravity="center_vertical"
android:singleLine="true"
tools:text="Menu Item" />
<TextView
android:id="@+id/bottom_sheet_menu_item_badge"
style="@style/MwmWidget.Counter"
android:layout_gravity="end|center_vertical"
android:visibility="gone"
tools:text="9999"
tools:visibility="visible" />
</LinearLayout>

View file

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/settings"
android:title="@string/list_settings"
android:icon="@drawable/ic_24_px_settings"/>
<item android:id="@+id/show_on_map"/>
<item android:id="@+id/share"
android:title="@string/export_file"
android:icon="@drawable/ic_share"/>
<item android:id="@+id/delete"
android:title="@string/delete"
android:icon="@drawable/ic_delete"/>
</menu>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/share"
android:title="@string/share"
android:icon="@drawable/ic_share"/>
<item android:id="@+id/edit"
android:title="@string/edit"
android:icon="@drawable/ic_edit"/>
<item android:id="@+id/delete"
android:title="@string/delete"
android:icon="@drawable/ic_delete"/>
</menu>

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/sort"
android:title="@string/sort"
android:icon="@drawable/ic_sort"/>
<item android:id="@+id/share_category"
android:title="@string/export_file"
android:icon="@drawable/ic_share"/>
<item android:id="@+id/settings"
android:title="@string/list_settings"
android:icon="@drawable/ic_24_px_settings"/>
<item android:id="@+id/delete_category"
android:title="@string/delete_list"
android:icon="@drawable/ic_delete"/>
</menu>

View file

@ -20,7 +20,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.cocosw.bottomsheet.BottomSheet;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.adapter.OnItemClickListener;
@ -33,20 +32,21 @@ import com.mapswithme.maps.dialog.DialogUtils;
import com.mapswithme.maps.dialog.EditTextDialogFragment;
import com.mapswithme.maps.widget.PlaceholderView;
import com.mapswithme.maps.widget.recycler.ItemDecoratorFactory;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.bottomsheet.MenuBottomSheetFragment;
import com.mapswithme.util.StorageUtils;
import com.mapswithme.util.bottomsheet.MenuBottomSheetItem;
import com.mapswithme.util.concurrency.ThreadPool;
import com.mapswithme.util.concurrency.UiThread;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<BookmarkCategoriesAdapter>
implements MenuItem.OnMenuItemClickListener,
BookmarkManager.BookmarksLoadingListener,
implements BookmarkManager.BookmarksLoadingListener,
CategoryListCallback,
OnItemClickListener<BookmarkCategory>,
OnItemMoreClickListener<BookmarkCategory>,
@ -155,49 +155,27 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
BookmarkManager.INSTANCE.removeCategoriesUpdatesListener(mCategoriesAdapterObserver);
}
@Override
public boolean onMenuItemClick(MenuItem item)
{
MenuItemClickProcessorWrapper processor = MenuItemClickProcessorWrapper
.getInstance(item.getItemId());
processor
.mInternalProcessor
.process(this, getSelectedCategory());
return true;
}
protected final void showBottomMenu(@NonNull BookmarkCategory item)
{
mSelectedCategory = item;
showBottomMenuInternal(item);
new MenuBottomSheetFragment(item.getName(), getMenuItems(item))
.show(getParentFragmentManager(), "bookmarkCategoriesBottomSheet");
}
private void showBottomMenuInternal(@NonNull BookmarkCategory item)
private ArrayList<MenuBottomSheetItem> getMenuItems(@NonNull BookmarkCategory item)
{
BottomSheetHelper.Builder bs = BottomSheetHelper.create(getActivity(), item.getName())
.sheet(getCategoryMenuResId())
.listener(this);
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
items.add(new MenuBottomSheetItem(R.string.list_settings, R.drawable.ic_settings, () -> onSettingsActionSelected(item)));
items.add(new MenuBottomSheetItem(
item.isVisible() ? R.string.hide : R.string.show,
item.isVisible() ? R.drawable.ic_hide : R.drawable.ic_show,
() -> onShowActionSelected(item)));
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_share, () -> onShareActionSelected(item)));
// Disallow deleting the last category
if (getAdapter().getBookmarkCategories().size() > 1)
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, () -> onDeleteActionSelected(item)));
BottomSheet bottomSheet = bs.build();
prepareBottomMenuItems(bottomSheet);
MenuItem menuItem = BottomSheetHelper.findItemById(bottomSheet, R.id.show_on_map);
menuItem.setIcon(item.isVisible() ? R.drawable.ic_hide : R.drawable.ic_show)
.setTitle(item.isVisible() ? R.string.hide : R.string.show);
BottomSheetHelper.tint(bottomSheet);
bottomSheet.show();
}
protected void prepareBottomMenuItems(@NonNull BottomSheet bottomSheet)
{
boolean isMultipleItems = getAdapter().getBookmarkCategories().size() > 1;
setEnableForMenuItem(R.id.delete, bottomSheet, isMultipleItems);
}
@MenuRes
protected int getCategoryMenuResId()
{
return R.menu.menu_bookmark_categories;
return items;
}
@Override
@ -264,21 +242,26 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
BookmarkListActivity.startForResult(this, category);
}
private void onShowActionSelected(@NonNull BookmarkCategory category)
{
BookmarkManager.INSTANCE.toggleCategoryVisibility(category);
getAdapter().notifyDataSetChanged();
}
protected void onShareActionSelected(@NonNull BookmarkCategory category)
{
BookmarksSharingHelper.INSTANCE.prepareBookmarkCategoryForSharing(getActivity(), category.getId());
BookmarksSharingHelper.INSTANCE.prepareBookmarkCategoryForSharing(requireActivity(), category.getId());
}
private void onDeleteActionSelected(@NonNull BookmarkCategory category)
{
BookmarkManager.INSTANCE.deleteCategory(category.getId());
getAdapter().notifyDataSetChanged();
onDeleteActionSelected();
}
protected void onDeleteActionSelected()
private void onSettingsActionSelected(@NonNull BookmarkCategory category)
{
// Do nothing.
BookmarkCategorySettingsActivity.startForResult(this, category);
}
@Override
@ -341,16 +324,6 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
showBottomMenu(category);
}
static void setEnableForMenuItem(@IdRes int id, @NonNull BottomSheet bottomSheet,
boolean enable)
{
BottomSheetHelper
.findItemById(bottomSheet, id)
.setVisible(enable)
.setEnabled(enable);
}
private void onSaveText(@NonNull String text)
{
if (mCategoryEditor != null)
@ -372,110 +345,6 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
void commit(@NonNull String newName);
}
protected enum MenuItemClickProcessorWrapper
{
SET_SHARE(R.id.share, shareAction()),
SHOW_ON_MAP(R.id.show_on_map, showAction()),
LIST_SETTINGS(R.id.settings, showListSettings()),
DELETE_LIST(R.id.delete, deleteAction());
@NonNull
private static MenuClickProcessorBase showListSettings()
{
return new MenuClickProcessorBase.OpenListSettings();
}
@NonNull
private static MenuClickProcessorBase.ShowAction showAction()
{
return new MenuClickProcessorBase.ShowAction();
}
@NonNull
private static MenuClickProcessorBase.ShareAction shareAction()
{
return new MenuClickProcessorBase.ShareAction();
}
@NonNull
private static MenuClickProcessorBase.DeleteAction deleteAction()
{
return new MenuClickProcessorBase.DeleteAction();
}
@IdRes
private final int mId;
@NonNull
private final MenuClickProcessorBase mInternalProcessor;
MenuItemClickProcessorWrapper(@IdRes int id, @NonNull MenuClickProcessorBase processorBase)
{
mId = id;
mInternalProcessor = processorBase;
}
@NonNull
public static MenuItemClickProcessorWrapper getInstance(@IdRes int resId)
{
for (MenuItemClickProcessorWrapper each : values())
{
if (each.mId == resId)
{
return each;
}
}
throw new IllegalArgumentException("Enum value for res id = " + resId + " not found");
}
}
protected static abstract class MenuClickProcessorBase
{
public abstract void process(@NonNull BookmarkCategoriesFragment frag,
@NonNull BookmarkCategory category);
protected static class ShowAction extends MenuClickProcessorBase
{
@Override
public void process(@NonNull BookmarkCategoriesFragment frag,
@NonNull BookmarkCategory category)
{
BookmarkManager.INSTANCE.toggleCategoryVisibility(category);
frag.getAdapter().notifyDataSetChanged();
}
}
protected static class ShareAction extends MenuClickProcessorBase
{
@Override
public void process(@NonNull BookmarkCategoriesFragment frag,
@NonNull BookmarkCategory category)
{
frag.onShareActionSelected(category);
}
}
protected static class DeleteAction extends MenuClickProcessorBase
{
@Override
public void process(@NonNull BookmarkCategoriesFragment frag,
@NonNull BookmarkCategory category)
{
frag.onDeleteActionSelected(category);
}
}
protected static class OpenListSettings extends MenuClickProcessorBase
{
@Override
public void process(@NonNull BookmarkCategoriesFragment frag,
@NonNull BookmarkCategory category)
{
BookmarkCategorySettingsActivity.startForResult(frag, category);
}
}
}
private static class CategoriesAdapterObserver implements DataChangedListener<BookmarkCategoriesFragment>
{
@Nullable

View file

@ -21,7 +21,6 @@ import androidx.recyclerview.widget.ConcatAdapter;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import com.cocosw.bottomsheet.BottomSheet;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.mapswithme.maps.MwmActivity;
import com.mapswithme.maps.R;
@ -40,11 +39,13 @@ import com.mapswithme.maps.search.SearchEngine;
import com.mapswithme.maps.widget.SearchToolbarController;
import com.mapswithme.maps.widget.placepage.EditBookmarkFragment;
import com.mapswithme.maps.widget.recycler.ItemDecoratorFactory;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.CrashlyticsUtils;
import com.mapswithme.util.SharingUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.bottomsheet.MenuBottomSheetFragment;
import com.mapswithme.util.bottomsheet.MenuBottomSheetItem;
import java.util.ArrayList;
import java.util.List;
public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter>
@ -615,24 +616,14 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
case BookmarkListAdapter.TYPE_BOOKMARK:
final BookmarkInfo bookmark = (BookmarkInfo) adapter.getItem(mSelectedPosition);
BottomSheet bs = BottomSheetHelper.create(requireActivity(), bookmark.getName())
.sheet(R.menu.menu_bookmarks)
.listener(this::onBookmarkMenuItemClicked)
.build();
BottomSheetHelper.tint(bs);
bs.show();
new MenuBottomSheetFragment(bookmark.getName(), getBookmarkMenuItems())
.show(getParentFragmentManager(), "bookmarkBottomSheet");
break;
case BookmarkListAdapter.TYPE_TRACK:
final Track track = (Track) adapter.getItem(mSelectedPosition);
BottomSheet bottomSheet = BottomSheetHelper
.create(requireActivity(), track.getName())
.sheet(Menu.NONE, R.drawable.ic_delete, R.string.delete)
.listener(menuItem -> onTrackMenuItemClicked(track.getTrackId()))
.build();
BottomSheetHelper.tint(bottomSheet);
bottomSheet.show();
new MenuBottomSheetFragment(track.getName(), getTrackMenuItems(track))
.show(getParentFragmentManager(), "trackBottomSheet");
break;
}
}
@ -644,69 +635,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
return false;
}
public boolean onBookmarkMenuItemClicked(@NonNull MenuItem menuItem)
{
BookmarkListAdapter adapter = getBookmarkListAdapter();
BookmarkInfo item = (BookmarkInfo) adapter.getItem(mSelectedPosition);
switch (menuItem.getItemId())
{
case R.id.share:
SharingUtils.shareBookmark(requireContext(), item);
break;
case R.id.edit:
EditBookmarkFragment.editBookmark(
item.getCategoryId(), item.getBookmarkId(), requireActivity(), getChildFragmentManager(),
(bookmarkId, movedFromCategory) ->
{
if (movedFromCategory)
resetSearchAndSort();
else
adapter.notifyDataSetChanged();
});
break;
case R.id.delete:
adapter.onDelete(mSelectedPosition);
BookmarkManager.INSTANCE.deleteBookmark(item.getBookmarkId());
adapter.notifyDataSetChanged();
if (mSearchMode)
mNeedUpdateSorting = true;
updateSearchVisibility();
updateRecyclerVisibility();
break;
}
return false;
}
public boolean onListMoreMenuItemClick(@NonNull MenuItem menuItem)
{
switch (menuItem.getItemId())
{
case R.id.sort:
ChooseBookmarksSortingTypeFragment.chooseSortingType(getAvailableSortingTypes(),
getLastSortingType(), requireActivity(), getChildFragmentManager());
return false;
case R.id.share_category:
long catId = mCategoryDataSource.getData().getId();
BookmarksSharingHelper.INSTANCE.prepareBookmarkCategoryForSharing(requireActivity(), catId);
return false;
case R.id.settings:
BookmarkCategorySettingsActivity.startForResult(this, mCategoryDataSource.getData());
return false;
case R.id.delete_category:
requireActivity().setResult(Activity.RESULT_OK);
requireActivity().finish();
return false;
}
return false;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.option_menu_bookmarks, menu);
@ -715,7 +645,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
}
@Override
public void onPrepareOptionsMenu(Menu menu)
public void onPrepareOptionsMenu(@NonNull Menu menu)
{
super.onPrepareOptionsMenu(menu);
@ -739,26 +669,103 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
if (item.getItemId() == R.id.bookmarks_more)
{
BottomSheet bs = BottomSheetHelper.create(requireActivity(),
mCategoryDataSource.getData().getName())
.sheet(R.menu.menu_bookmarks_list)
.listener(this::onListMoreMenuItemClick)
.build();
@BookmarkManager.SortingType int[] types = getAvailableSortingTypes();
Menu moreMenu = bs.getMenu();
moreMenu.findItem(R.id.sort).setVisible(types.length > 0 && !isEmpty());
moreMenu.findItem(R.id.delete_category).setVisible(!isLastOwnedCategory());
moreMenu.findItem(R.id.share_category).setVisible(!isEmpty());
BottomSheetHelper.tint(bs);
bs.show();
new MenuBottomSheetFragment(mCategoryDataSource.getData().getName(), getOptionsMenuItems())
.show(getParentFragmentManager(), "optionsBottomSheet");
return true;
}
return super.onOptionsItemSelected(item);
}
private void onShareActionSelected()
{
BookmarkInfo info = (BookmarkInfo) getBookmarkListAdapter().getItem(mSelectedPosition);
SharingUtils.shareBookmark(requireContext(), info);
}
private void onEditActionSelected()
{
BookmarkListAdapter adapter = getBookmarkListAdapter();
BookmarkInfo info = (BookmarkInfo) adapter.getItem(mSelectedPosition);
EditBookmarkFragment.editBookmark(
info.getCategoryId(), info.getBookmarkId(), requireActivity(), getChildFragmentManager(),
(bookmarkId, movedFromCategory) ->
{
if (movedFromCategory)
resetSearchAndSort();
else
adapter.notifyDataSetChanged();
});
}
private void onDeleteActionSelected()
{
BookmarkListAdapter adapter = getBookmarkListAdapter();
BookmarkInfo info = (BookmarkInfo) getBookmarkListAdapter().getItem(mSelectedPosition);
adapter.onDelete(mSelectedPosition);
BookmarkManager.INSTANCE.deleteBookmark(info.getBookmarkId());
adapter.notifyDataSetChanged();
if (mSearchMode)
mNeedUpdateSorting = true;
updateSearchVisibility();
updateRecyclerVisibility();
}
private void onSortOptionSelected()
{
ChooseBookmarksSortingTypeFragment.chooseSortingType(getAvailableSortingTypes(),
getLastSortingType(), requireActivity(), getChildFragmentManager());
}
private void onShareOptionSelected()
{
long catId = mCategoryDataSource.getData().getId();
BookmarksSharingHelper.INSTANCE.prepareBookmarkCategoryForSharing(requireActivity(), catId);
}
private void onSettingsOptionSelected()
{
BookmarkCategorySettingsActivity.startForResult(this, mCategoryDataSource.getData());
}
private void onDeleteOptionSelected()
{
requireActivity().setResult(Activity.RESULT_OK);
requireActivity().finish();
}
private ArrayList<MenuBottomSheetItem> getOptionsMenuItems()
{
@BookmarkManager.SortingType int[] types = getAvailableSortingTypes();
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
if (!isEmpty())
{
if (types.length > 0)
items.add(new MenuBottomSheetItem(R.string.sort, R.drawable.ic_sort, this::onSortOptionSelected));
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_share, this::onShareOptionSelected));
}
items.add(new MenuBottomSheetItem(R.string.list_settings, R.drawable.ic_settings, this::onSettingsOptionSelected));
if (!isLastOwnedCategory())
items.add(new MenuBottomSheetItem(R.string.delete_list, R.drawable.ic_delete, this::onDeleteOptionSelected));
return items;
}
private ArrayList<MenuBottomSheetItem> getBookmarkMenuItems()
{
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
items.add(new MenuBottomSheetItem(R.string.share, R.drawable.ic_share, this::onShareActionSelected));
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_edit, this::onEditActionSelected));
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, this::onDeleteActionSelected));
return items;
}
private ArrayList<MenuBottomSheetItem> getTrackMenuItems(final Track track)
{
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, () -> onTrackMenuItemClicked(track.getTrackId())));
return items;
}
@Override
public void onPreparedFileForSharing(@NonNull BookmarkSharingResult result)
{

View file

@ -1,7 +1,6 @@
package com.mapswithme.maps.downloader;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Typeface;
import android.location.Location;
@ -15,24 +14,22 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.cocosw.bottomsheet.BottomSheet;
import com.mapswithme.maps.MwmActivity;
import com.mapswithme.maps.R;
import com.mapswithme.maps.intent.Factory;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.routing.RoutingController;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.StringUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.bottomsheet.MenuBottomSheetFragment;
import com.mapswithme.util.bottomsheet.MenuBottomSheetItem;
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter;
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;
@ -72,124 +69,74 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
private int mListenerSlot;
private enum MenuItem
private void onDownloadActionSelected(final CountryItem item, DownloaderAdapter adapter)
{
DOWNLOAD(R.drawable.ic_download, R.string.downloader_download_map)
MapManager.warn3gAndDownload(adapter.mActivity, item.id, null);
}
private void onUpdateActionSelected(final CountryItem item, DownloaderAdapter adapter)
{
item.update();
if (item.status != CountryItem.STATUS_UPDATABLE)
return;
MapManager.warnOn3gUpdate(adapter.mActivity, item.id, () -> MapManager.nativeUpdate(item.id));
}
private void onExploreActionSelected(CountryItem item, DownloaderAdapter adapter)
{
Intent intent = new Intent(adapter.mActivity, MwmActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra(MwmActivity.EXTRA_TASK, new Factory.ShowCountryTask(item.id));
adapter.mActivity.startActivity(intent);
if (!(adapter.mActivity instanceof MwmActivity))
adapter.mActivity.finish();
}
void onDeleteActionSelected(final CountryItem item, final DownloaderAdapter adapter)
{
if (RoutingController.get().isNavigating())
{
@Override
void invoke(final CountryItem item, DownloaderAdapter adapter)
{
MapManager.warn3gAndDownload(adapter.mActivity, item.id, null);
}
},
DELETE(R.drawable.ic_delete, R.string.delete)
{
private void deleteNode(CountryItem item)
{
MapManager.nativeCancel(item.id);
MapManager.nativeDelete(item.id);
OnmapDownloader.setAutodownloadLocked(true);
}
@Override
void invoke(final CountryItem item, final DownloaderAdapter adapter)
{
if (RoutingController.get().isNavigating())
{
new AlertDialog.Builder(adapter.mActivity)
.setTitle(R.string.downloader_delete_map)
.setMessage(R.string.downloader_delete_map_while_routing_dialog)
.setPositiveButton(android.R.string.ok, null)
.show();
return;
}
if (!MapManager.nativeHasUnsavedEditorChanges(item.id))
{
deleteNode(item, adapter);
return;
}
new AlertDialog.Builder(adapter.mActivity)
.setTitle(R.string.downloader_delete_map)
.setMessage(R.string.downloader_delete_map_dialog)
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
deleteNode(item, adapter);
}
}).show();
}
private void deleteNode(CountryItem item, DownloaderAdapter adapter)
{
if (adapter.mActivity instanceof MwmActivity)
{
((MwmActivity) adapter.mActivity).closePlacePage();
}
deleteNode(item);
}
},
CANCEL(R.drawable.ic_cancel, R.string.cancel)
{
@Override
void invoke(CountryItem item, DownloaderAdapter adapter)
{
MapManager.nativeCancel(item.id);
}
},
EXPLORE(R.drawable.ic_explore, R.string.zoom_to_country)
{
@Override
void invoke(CountryItem item, DownloaderAdapter adapter)
{
Intent intent = new Intent(adapter.mActivity, MwmActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra(MwmActivity.EXTRA_TASK, new Factory.ShowCountryTask(item.id));
adapter.mActivity.startActivity(intent);
if (!(adapter.mActivity instanceof MwmActivity))
adapter.mActivity.finish();
}
},
UPDATE(R.drawable.ic_update, R.string.downloader_update_map)
{
@Override
void invoke(final CountryItem item, DownloaderAdapter adapter)
{
item.update();
if (item.status != CountryItem.STATUS_UPDATABLE)
return;
MapManager.warnOn3gUpdate(adapter.mActivity, item.id, new Runnable()
{
@Override
public void run()
{
MapManager.nativeUpdate(item.id);
}
});
}
};
final @DrawableRes int icon;
final @StringRes int title;
MenuItem(@DrawableRes int icon, @StringRes int title)
{
this.icon = icon;
this.title = title;
new AlertDialog.Builder(adapter.mActivity)
.setTitle(R.string.downloader_delete_map)
.setMessage(R.string.downloader_delete_map_while_routing_dialog)
.setPositiveButton(android.R.string.ok, null)
.show();
return;
}
abstract void invoke(CountryItem item, DownloaderAdapter adapter);
if (!MapManager.nativeHasUnsavedEditorChanges(item.id))
{
deleteNode(item, adapter);
return;
}
new AlertDialog.Builder(adapter.mActivity)
.setTitle(R.string.downloader_delete_map)
.setMessage(R.string.downloader_delete_map_dialog)
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, (dialog, which) -> deleteNode(item, adapter)).show();
}
private void onCancelActionSelected(CountryItem item, DownloaderAdapter adapter)
{
MapManager.nativeCancel(item.id);
}
private void deleteNode(CountryItem item)
{
MapManager.nativeCancel(item.id);
MapManager.nativeDelete(item.id);
OnmapDownloader.setAutodownloadLocked(true);
}
private void deleteNode(CountryItem item, DownloaderAdapter adapter)
{
if (adapter.mActivity instanceof MwmActivity)
{
((MwmActivity) adapter.mActivity).closePlacePage();
}
deleteNode(item);
}
private static class PathEntry
@ -335,7 +282,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
case CountryItem.STATUS_DOWNLOADABLE:
case CountryItem.STATUS_PARTLY:
if (clickOnStatus)
MenuItem.DOWNLOAD.invoke(mItem, DownloaderAdapter.this);
onDownloadActionSelected(mItem, DownloaderAdapter.this);
else
processLongClick();
break;
@ -364,68 +311,85 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
private void processLongClick()
{
List<MenuItem> items = new ArrayList<>();
ArrayList<MenuBottomSheetItem> items = getMenuItems();
new MenuBottomSheetFragment(mItem.name, items)
.show(mFragment.getParentFragmentManager(), "downloaderBottomSheet");
}
private MenuBottomSheetItem getDownloadMenuItem()
{
return new MenuBottomSheetItem(R.string.downloader_download_map, R.drawable.ic_download,
() -> onDownloadActionSelected(mItem, DownloaderAdapter.this));
}
private MenuBottomSheetItem getUpdateMenuItem()
{
return new MenuBottomSheetItem(R.string.downloader_update_map, R.drawable.ic_update,
() -> onUpdateActionSelected(mItem, DownloaderAdapter.this));
}
private MenuBottomSheetItem getExploreMenuItem()
{
return new MenuBottomSheetItem(R.string.zoom_to_country, R.drawable.ic_explore,
() -> onExploreActionSelected(mItem, DownloaderAdapter.this));
}
private MenuBottomSheetItem getDeleteMenuItem()
{
return new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete,
() -> onDeleteActionSelected(mItem, DownloaderAdapter.this));
}
private MenuBottomSheetItem getCancelMenuItem()
{
return new MenuBottomSheetItem(R.string.cancel, R.drawable.ic_cancel,
() -> onCancelActionSelected(mItem, DownloaderAdapter.this));
}
private ArrayList<MenuBottomSheetItem> getMenuItems()
{
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
switch (mItem.status)
{
case CountryItem.STATUS_DOWNLOADABLE:
items.add(MenuItem.DOWNLOAD);
break;
case CountryItem.STATUS_DOWNLOADABLE:
items.add(getDownloadMenuItem());
break;
case CountryItem.STATUS_UPDATABLE:
items.add(MenuItem.UPDATE);
// No break
case CountryItem.STATUS_UPDATABLE:
items.add(getUpdateMenuItem());
// Fallthrough
case CountryItem.STATUS_DONE:
if (!mItem.isExpandable())
items.add(MenuItem.EXPLORE);
case CountryItem.STATUS_DONE:
if (!mItem.isExpandable())
items.add(getExploreMenuItem());
items.add(getDeleteMenuItem());
break;
items.add(MenuItem.DELETE);
break;
case CountryItem.STATUS_FAILED:
items.add(getCancelMenuItem());
case CountryItem.STATUS_FAILED:
items.add(MenuItem.CANCEL);
if (mItem.present)
{
items.add(getDeleteMenuItem());
items.add(getExploreMenuItem());
}
break;
if (mItem.present)
{
items.add(MenuItem.DELETE);
items.add(MenuItem.EXPLORE);
}
break;
case CountryItem.STATUS_PROGRESS:
case CountryItem.STATUS_APPLYING:
case CountryItem.STATUS_ENQUEUED:
items.add(getCancelMenuItem());
case CountryItem.STATUS_PROGRESS:
case CountryItem.STATUS_APPLYING:
case CountryItem.STATUS_ENQUEUED:
items.add(MenuItem.CANCEL);
if (mItem.present)
items.add(getExploreMenuItem());
break;
if (mItem.present)
items.add(MenuItem.EXPLORE);
break;
case CountryItem.STATUS_PARTLY:
items.add(MenuItem.DOWNLOAD);
items.add(MenuItem.DELETE);
break;
case CountryItem.STATUS_PARTLY:
items.add(getDownloadMenuItem());
items.add(getDeleteMenuItem());
break;
}
if (items.isEmpty())
return;
BottomSheetHelper.Builder bs = BottomSheetHelper.create(mActivity, mItem.name);
for (MenuItem item: items)
bs.sheet(item.ordinal(), item.icon, item.title);
BottomSheet bottomSheet = bs.listener(new android.view.MenuItem.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(android.view.MenuItem item)
{
MenuItem.values()[item.getItemId()].invoke(mItem, DownloaderAdapter.this);
return false;
}
}).build();
BottomSheetHelper.tint(bottomSheet);
bottomSheet.show();
return items;
}
ItemViewHolder(View frame)

View file

@ -1,29 +1,25 @@
package com.mapswithme.maps.editor;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import com.cocosw.bottomsheet.BottomSheet;
import com.mapswithme.maps.BuildConfig;
import com.mapswithme.maps.R;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.Constants;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.bottomsheet.MenuBottomSheetFragment;
import com.mapswithme.util.bottomsheet.MenuBottomSheetItem;
import com.mapswithme.util.concurrency.ThreadPool;
import com.mapswithme.util.concurrency.UiThread;
import java.util.ArrayList;
import java.util.List;
public class ProfileFragment extends AuthFragment implements View.OnClickListener
{
@ -33,40 +29,18 @@ public class ProfileFragment extends AuthFragment implements View.OnClickListene
private View mAuthBlock;
private View mRatingBlock;
private enum MenuItem
private void onLogoutActionSelected(final ProfileFragment fragment)
{
LOGOUT(R.drawable.ic_logout, R.string.logout)
{
@Override
void invoke(final ProfileFragment fragment)
{
new AlertDialog.Builder(fragment.requireContext())
.setMessage(R.string.are_you_sure)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
OsmOAuth.clearAuthorization(fragment.requireContext());
fragment.refreshViews();
}
})
.setNegativeButton(android.R.string.no, null)
.create()
.show();
}
};
final @DrawableRes int icon;
final @StringRes int title;
MenuItem(@DrawableRes int icon, @StringRes int title)
{
this.icon = icon;
this.title = title;
}
abstract void invoke(ProfileFragment fragment);
new AlertDialog.Builder(fragment.requireContext())
.setMessage(R.string.are_you_sure)
.setPositiveButton(android.R.string.ok, (dialog, which) ->
{
OsmOAuth.clearAuthorization(fragment.requireContext());
fragment.refreshViews();
})
.setNegativeButton(android.R.string.no, null)
.create()
.show();
}
@Override
@ -135,23 +109,8 @@ public class ProfileFragment extends AuthFragment implements View.OnClickListene
private void showBottomSheet()
{
List<MenuItem> items = new ArrayList<>();
items.add(MenuItem.LOGOUT);
BottomSheetHelper.Builder bs = BottomSheetHelper.create(getActivity());
for (MenuItem item: items)
bs.sheet(item.ordinal(), item.icon, item.title);
BottomSheet bottomSheet = bs.listener(new android.view.MenuItem.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(android.view.MenuItem item)
{
MenuItem.values()[item.getItemId()].invoke(ProfileFragment.this);
return false;
}
}).build();
BottomSheetHelper.tint(bottomSheet);
bottomSheet.show();
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
items.add(new MenuBottomSheetItem(R.string.logout, R.drawable.ic_logout, () -> onLogoutActionSelected(ProfileFragment.this)));
new MenuBottomSheetFragment(items).show(getParentFragmentManager(), "profileBottomSheet");
}
}

View file

@ -2,7 +2,6 @@ package com.mapswithme.maps.widget.placepage;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -12,13 +11,13 @@ import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import com.cocosw.bottomsheet.BottomSheet;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.routing.RoutingController;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.bottomsheet.MenuBottomSheetFragment;
import com.mapswithme.util.bottomsheet.MenuBottomSheetItem;
import java.util.ArrayList;
import java.util.Collections;
@ -309,27 +308,22 @@ public final class PlacePageButtons
}
}
private void showPopup(final List<PlacePageButton> buttons)
private ArrayList<MenuBottomSheetItem> getMenuItems(final List<PlacePageButton> buttons)
{
BottomSheetHelper.Builder bs = new BottomSheetHelper.Builder(mPlacePage.getActivity());
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
for (int i = mMaxButtons; i < buttons.size(); i++)
{
PlacePageButton bsItem = buttons.get(i);
int iconRes = bsItem.getIcon().getEnabledStateResId(mPlacePage.getContext());
bs.sheet(i, iconRes, bsItem.getTitle());
items.add(new MenuBottomSheetItem(bsItem.getTitle(), iconRes, () -> mItemListener.onItemClick(bsItem)));
}
return items;
}
BottomSheet bottomSheet = bs.listener(new MenuItem.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(MenuItem item)
{
mItemListener.onItemClick(buttons.get(item.getItemId()));
return true;
}
}).build();
BottomSheetHelper.tint(bottomSheet);
bottomSheet.show();
private void showPopup(final List<PlacePageButton> buttons)
{
new MenuBottomSheetFragment(getMenuItems(buttons))
.show(mPlacePage.getActivity().getSupportFragmentManager(), "moreBottomSheet");
}
private View createButton(@NonNull final List<PlacePageButton> items,

View file

@ -0,0 +1,106 @@
package com.mapswithme.util.bottomsheet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import java.util.ArrayList;
public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.ViewHolder>
{
private final ArrayList<MenuBottomSheetItem> dataSet;
@Nullable
private final MenuBottomSheetItem.OnClickListener onClickListener;
public MenuAdapter(ArrayList<MenuBottomSheetItem> dataSet, @Nullable MenuBottomSheetItem.OnClickListener onClickListener)
{
this.dataSet = dataSet;
this.onClickListener = onClickListener;
}
private void onMenuItemClick(MenuBottomSheetItem item)
{
if (onClickListener != null)
onClickListener.onClick();
item.onClickListener.onClick();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
{
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.bottom_sheet_menu_item, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position)
{
final MenuBottomSheetItem item = dataSet.get(position);
viewHolder.getContainer().setOnClickListener((v) -> onMenuItemClick(item));
viewHolder.getIconImageView().setImageResource(item.iconRes);
viewHolder.getTitleTextView().setText(item.titleRes);
TextView badge = viewHolder.getBadgeTextView();
if (item.badgeCount > 0)
{
badge.setText(String.valueOf(item.badgeCount));
badge.setVisibility(View.VISIBLE);
} else {
badge.setVisibility(View.GONE);
}
}
@Override
public int getItemCount()
{
return dataSet.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
private final LinearLayout container;
private final ImageView iconImageView;
private final TextView titleTextView;
private final TextView badgeTextView;
public ViewHolder(View view)
{
super(view);
container = view.findViewById(R.id.bottom_sheet_menu_item);
iconImageView = view.findViewById(R.id.bottom_sheet_menu_item_icon);
titleTextView = view.findViewById(R.id.bottom_sheet_menu_item_text);
badgeTextView = view.findViewById(R.id.bottom_sheet_menu_item_badge);
}
public ImageView getIconImageView()
{
return iconImageView;
}
public TextView getTitleTextView()
{
return titleTextView;
}
public TextView getBadgeTextView()
{
return badgeTextView;
}
public LinearLayout getContainer()
{
return container;
}
}
}

View file

@ -0,0 +1,79 @@
package com.mapswithme.util.bottomsheet;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.mapswithme.maps.R;
import java.util.ArrayList;
public class MenuBottomSheetFragment extends BottomSheetDialogFragment
{
@Nullable
private final String title;
private final ArrayList<MenuBottomSheetItem> menuBottomSheetItems;
public MenuBottomSheetFragment(@NonNull String title, ArrayList<MenuBottomSheetItem> menuBottomSheetItems)
{
this.title = title;
this.menuBottomSheetItems = menuBottomSheetItems;
}
public MenuBottomSheetFragment(ArrayList<MenuBottomSheetItem> menuBottomSheetItems)
{
this.title = null;
this.menuBottomSheetItems = menuBottomSheetItems;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
return inflater.inflate(R.layout.bottom_sheet, container);
}
@Override
public void onStart()
{
super.onStart();
BottomSheetBehavior<View> behavior = BottomSheetBehavior.from((View) requireView().getParent());
// By default sheets in landscape start at their peek height.
// We fix this by forcing the expanded state and disabling the collapsed one
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
behavior.setSkipCollapsed(true);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
TextView titleView = view.findViewById(R.id.bottomSheetTitle);
RecyclerView recyclerView = view.findViewById(R.id.bottomSheetMenuContainer);
if (title != null)
{
titleView.setVisibility(View.VISIBLE);
titleView.setText(title);
} else
titleView.setVisibility(View.GONE);
MenuAdapter menuAdapter = new MenuAdapter(menuBottomSheetItems, this::dismiss);
recyclerView.setAdapter(menuAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
}
}

View file

@ -0,0 +1,30 @@
package com.mapswithme.util.bottomsheet;
public class MenuBottomSheetItem
{
public final int titleRes;
public final int iconRes;
public final int badgeCount;
public final OnClickListener onClickListener;
public MenuBottomSheetItem(int titleRes, int iconRes, OnClickListener onClickListener)
{
this.titleRes = titleRes;
this.iconRes = iconRes;
this.badgeCount = 0;
this.onClickListener = onClickListener;
}
public MenuBottomSheetItem(int titleRes, int iconRes, int badgeCount, OnClickListener onClickListener)
{
this.titleRes = titleRes;
this.iconRes = iconRes;
this.badgeCount = badgeCount;
this.onClickListener = onClickListener;
}
public interface OnClickListener
{
void onClick();
}
}