BottomSheetDialog get Behavour always returns null

爱⌒轻易说出口 提交于 2019-12-11 02:44:33

问题


I working with BottomSheetDialog and i have to get Behavior so can set setBottomSheetCallback() to handle some stuff.

As google says i had to put Coordinator on parentView and add behavior to it. I defined CoordinatorLayout in MainActivity (root activity) like this:

<android.support.design.widget.CoordinatorLayout
    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:tag="coordinatorLayout"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"

...

This is try to get from activity:

 public void setupDialog(final Dialog dialog, int style) {

 CoordinatorLayout coordinatorLayout = getActivity().getWindow().getDecorView();
 BottomSheetBehavior behavior = BottomSheetBehavior.from(coordinatorLayout);

I also tried:

CoordinatorLayout coordinatorLayout = getActivity().getWindow().getDecorView().findViewById(R.id.coordinatorLayout); 
//this is point to the coordinatorView 

BottomSheetBehavior behavior = BottomSheetBehavior.from(coordinatorLayout);
//But this returns same error that "The view is not a child of CoordinatorLayout"

As you see i passed the coordinator-layout but method can not find behavior in it. I also should mention to points in using BottonSheetDialog:

  1. I show my BottonSheetFragments like this:
  2. I inflated my BottomSheetDialog in OnCreateView (not in setupDialog()) for ability of adding View Pager inside. As you may know ViewPager wont attach to BottonSheetDialog if you inflate view in onSetupDialog().

Any way i could not get behavior of CoordinatorLayout of parent. In my bottonSheetDialog i try these methods and non of them works and i get "The view is not a child of CoordinatorLayout" error.

code for point 1:

MyFragment myFragment= MyFragment.getInstance(bundle);
myFragment.show(fragment.getChildFragmentManager(),"tag");

code for point 2:

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_bottomsheet, null, false);  
return rootView;
}

回答1:


BottomSheetDialog is a rather peculiar Dialog implementation. It is not added to, nor does it rely on*, a CoordinatorLayout in your Activity's layout. It sets up its own CoordinatorLayout internally, and within that, a FrameLayout with BottomSheetBehavior, into which your View is placed. The BottomSheetDialog itself fills the whole screen, and has a transparent background, so that it can handle the bottom sheet interaction, and any outside touches.

If you need access to that bottom sheet and its BottomSheetBehavior, we'll need to get it from the Dialog's View hierarchy. That's as simple as calling findViewById(R.id.design_bottom_sheet) on the Dialog, but we'll need to wait until the Dialog is shown to modify the BottomSheetBehavior. Furthermore, since BottomSheetDialog sets its own BottomSheetCallback, we must ensure that we replace it appropriately. That is, we must take care of cancelling the Dialog when it hits the closed state. For example:

final BottomSheetDialog bsd = new BottomSheetDialog(MainActivity.this);
bsd.setContentView(R.layout.your_dialog_layout);
bsd.show();

FrameLayout bottomSheet = (FrameLayout) bsd.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(View bottomSheet, int newState) {
            // This is the crucial bit.
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                bsd.cancel();
            }
        }

        @Override
        public void onSlide(View bottomSheet, float slideOffset) {}
    }
);

If you're using a BottomSheetDialogFragment, the Dialog is shown in DialogFragment's onStart(), and we can override that method to do our modifications there, after the super call. For example:

public class MyFragment extends BottomSheetDialogFragment {
    public MyFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.your_dialog_layout, container, false);
    }

    @Override
    public void onStart() {
        super.onStart();

        FrameLayout bottomSheet = getDialog().findViewById(R.id.design_bottom_sheet);
        BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                @Override
                public void onStateChanged(View bottomSheet, int newState) {
                    // This is the crucial bit.
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        getDialog().cancel();
                    }
                }

                @Override
                public void onSlide(View bottomSheet, float slideOffset) {}
            }
        );
    }
}

In either case, you can do pretty much whatever you want in the BottomSheetCallback, as long as you cancel() the Dialog in onStateChanged() when newState == BottomSheetBehavior.STATE_HIDDEN.


*Incidentally, this means that you do not have to have a CoordinatorLayout in your Activity'a layout to use BottomSheetDialog or BottomSheetDialogFragment, though I'm not sure that's made clear anywhere in the documentation or other developer resources.




回答2:


in your CoordinatorLayout you have child that have this app:layout_behavior="android.support.design.widget.BottomSheetBehavior"

so you need to make BottomSheetBehavior behavior = BottomSheetBehavior.from(your CoordinatorLayout child);

And on it you need to make setBottomSheetCallback. behavior.setBottomSheetCallback(...)



来源:https://stackoverflow.com/questions/53360648/bottomsheetdialog-get-behavour-always-returns-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!