Opening bottom sheet when clicked on the overflow menu on a fragment

2.1k Views Asked by At

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.

3

There are 3 best solutions below

1
user158 On BEST ANSWER

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.

5
Alok Singh On
 **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;
     }
    }
3
Anmol On

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