1

I am trying to implement behavior of opening bottom sheet when clicked on overflow menu. ex: expected behavior

I may do this on an activity using onMenuOpened as suggested here, But I want to do this on fragment.

How to achieve this behavior on a fragment?

I am using single activity pattern and navigation architecture component.

user158
  • 12,852
  • 7
  • 62
  • 94

3 Answers3

1

Create a interface which will be implemented by your Fragment's

ex:

public interface OnMenuOpenListener(){
  boolean onMenuOpened(); 
}

public class MyFragment extends Fragment implements OnMenuOpenListener{
   @Override
   public boolean onMenuOpened(){
    //open bottom sheet here
   }
}

public class MyActivity extends Activity{
   @Override
   public boolean onMenuOpened(int featureId, Menu menu) {
      if(featureId == AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR && menu != null){
        //overflow menu clicked, put code here...
        // As you are using navigation component
        Fragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host);
        //MyFragment
        Fragment fragment=navHostFragment.getChildFragmentManager().getFragments().get(0);
        if(fragment instanceof OnMenuOpenListener){
           ((OnMenuOpenListener)fragment).onMenuOpened()
          return false;
        }
      }
       return super.onMenuOpened(featureId, menu);
   }
}

As Support Action Bar is attached to Activity All the event's are captured by Activity all you need to do is get the Fragment which need's the event and trigger the call using a call back.If you return false onMenuOpened will not open the overflow menu and will trigger bottom sheet menu from your fragment.

P.S- I have not written the code in Editor so might have some error's but you must have got the idea.

Reference: https://stackoverflow.com/a/51732378/7972699

Anmol
  • 8,110
  • 9
  • 38
  • 63
  • While this does work it still opens the context menu, by the way there was an error in your code I will suggest an edit – user158 Jul 26 '19 at 08:34
  • @user158 even when you return false from `onMenuOpened` of activity? – Anmol Jul 26 '19 at 09:05
  • yes false was returned, anyway thanks for help, I decided to go with normal context menu since bottom sheet with overflow menu is bad UX – user158 Jul 26 '19 at 09:57
1

As discussed here opening bottom sheet when clicked on the overflow menu is bad UX.

Why?

Quoting from the post

Because user have to reach the top of the screen to click the oveflow menu, then go back to the bottom to click desired action which is on the bottom sheet.

-

According to Fitt's Law - The time to acquire a target is a function of the distance to and size of the target. I agree that I think distance between the menu and the bottom sheet is substantial. This solution allows placing a lot options in one place.

-

it also doesn't match the user expectation since people are used to the overflow menu opening in a different manner.

If you have a top action bar, use usual context menu. If you have a bottom action bar you may use bottom sheet.

user158
  • 12,852
  • 7
  • 62
  • 94
  • 1
    Material.io suggests otherwise. See the example here - https://material.io/components/sheets-bottom#modal-bottom-sheet then scroll down a little to the "Behavior" sub-section. – Calum Templeton Oct 25 '20 at 10:12
0
 **You can try the following steps to open bottom sheet dialog:** 

1. Just make a function inside Activity where the fragment is replace


public Fragment getCurrentFragment() {
      return getSupportFragmentManager().findFragmentById(R.id.frameContainer);
     }

     Fragment fragment = getCurrentFragment();
     if (fragment != null) {
      if (fragment instanceof RequiredFragment) {
       RequiredFragment.openBottumSheetDialog();

      }
     }



2. In Side RequiredFragment get your function from activity:



 private BottomSheetDialog mBottomSheetDialogFragment;

 private void showBottomSheetFilter() {
   if (mBottomSheetDialogFragment == null) {
    mBottomSheetDialogFragment = mBottomSheetDialogFragment.newInstance(feedSection);
    mBottomSheetDialogFragment.setCallBackListener(new OnFeedsTypeSelectedListener() {
      @Override
      public void onFeedsTypeSelected(int contentType) {
       filterByContentTypeId(contentType);
      }

     }
     mBottomSheetDialogFragment.show(getChildFragmentManager(),
      mBottomSheetDialogFragment.getTag());
    }

3. Create a BottomSheetDialog Dialog fragment.



public class BottomSheetDialog extends BottomSheetDialogFragment {

     private String[] feedsFilter;
     private ListView listView;


     @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      feedsFilter = getResources().getStringArray(R.array.ideas_filter);
     }

     @Override
     public void setupDialog(final Dialog dialog, int style) {
      super.setupDialog(dialog, style);
      View contentView = View.inflate(getContext(), R.layout.dialog_idea_filter_bottom_sheet, null);
      dialog.setContentView(contentView);

      listView = (ListView) contentView.findViewById(R.id.listView);
      ArrayAdapter < String > adapter = new ArrayAdapter < String > (getActivity(),
       android.R.layout.simple_list_item_1, feedsFilter);
      listView.setAdapter(adapter);

      listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
       @Override
       public void onItemClick(AdapterView < ? > parent, View view,
        int position, long id) {
        if (onFeedsTypeSelected != null) {
         onIdeaTypeSelectedListenonFeedsTypeSelecteder.onFeedsTypeSelected(feedsFilter[position]);
        }
        dismiss();
       }
      });
     }


     public void setCallBackListener(onFeedsTypeSelected SelectedListener onFeedsTypeSelected) {
      this.onIdeaTypeSelectedLionFeedsTypeSelectedstener = onFeedsTypeSelected;
     }
    }
Alok Singh
  • 640
  • 4
  • 14
  • Thanks for the effort. But this is not just about showing a bottom sheet – user158 Jul 26 '19 at 06:33
  • @user158..then what is required other than this. – Alok Singh Jul 26 '19 at 06:36
  • I want to bottom sheet to be shown when tap on the overflow men, when user on fragment screen, since there is no `onMenuOpened` on fragment level – user158 Jul 26 '19 at 06:40
  • You can get @Override public boolean onOptionsItemSelected(MenuItem menuItem) { if (menuItem.getItemId() == R.id.account_item) { callAbove fuction in Activity.} in side your Activity. – Alok Singh Jul 26 '19 at 06:41
  • there is no options context menu in my case just. please look at the video on expected behavior – user158 Jul 26 '19 at 06:45