Android BottomSheetDialog get Behavour始终返回null
我使用的是BottomSheetDialog,我必须获得行为,这样才能设置setBottomSheetCallback()来处理一些事情 因为我必须将协调器放在parentView上,并向其中添加行为。我在MainActivity(根活动)中定义了CoordinatorLayout,如下所示:Android BottomSheetDialog get Behavour始终返回null,android,android-coordinatorlayout,behavior,Android,Android Coordinatorlayout,Behavior,我使用的是BottomSheetDialog,我必须获得行为,这样才能设置setBottomSheetCallback()来处理一些事情 因为我必须将协调器放在parentView上,并向其中添加行为。我在MainActivity(根活动)中定义了CoordinatorLayout,如下所示: <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/
<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"
...
我还尝试:
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"
如您所见,我传递了协调器布局,但方法无法在其中找到行为。
我还应该提到使用BottonSheetDialog的要点:
MyFragment myFragment= MyFragment.getInstance(bundle);
myFragment.show(fragment.getChildFragmentManager(),"tag");
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_bottomsheet, null, false);
return rootView;
}
MyFragment myFragment= MyFragment.getInstance(bundle);
myFragment.show(fragment.getChildFragmentManager(),"tag");
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_bottomsheet, null, false);
return rootView;
}
第2点的代码:
MyFragment myFragment= MyFragment.getInstance(bundle);
myFragment.show(fragment.getChildFragmentManager(),"tag");
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_bottomsheet, null, false);
return rootView;
}
在您的CoordinatorLayout中,您有一个孩子有这个
应用程序:layout\u behavior=“android.support.design.widget.BottomSheetBehavior”
因此,您需要使BottomSheetBehavior=BottomSheetBehavior.from(您的CoordinatorLayout孩子)代码>
在它上面,你需要做setBottomSheetCallback。
behavior.setBottomSheetCallback(…)
BottomSheetDialog
是一个非常独特的对话框
实现。它不添加到您的活动
布局中的协调布局
,也不依赖*。它在内部设置自己的协调布局
,并在其中设置一个框架布局
,其中包含底部挡板行为
,您的视图
将放置在其中。BottomSheetDialog
本身填充整个屏幕,并具有透明的背景,因此它可以处理底部工作表交互和任何外部触摸
如果您需要访问该底部工作表及其底部工作表行为
,我们需要从对话框
的视图
层次结构中获取它。这很简单,只需在对话框中调用findViewById(R.id.design\u bottom\u sheet)
,但我们需要等到显示对话框时才能修改bottomsheet行为。此外,由于BottomSheetDialog
设置了自己的BottomSheetCallback
,因此我们必须确保适当地替换它。也就是说,我们必须注意在对话框进入关闭状态时取消它。例如:
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) {}
}
);
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) {}
}
);
}
}
如果您使用的是DialogFragment
,则对话框
显示在DialogFragment
的onStart()
中,我们可以在调用super
后重写该方法在那里进行修改。例如:
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) {}
}
);
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) {}
}
);
}
}
在这两种情况下,只要在onStateChanged()
中cancel()
当newState==BottomSheetBehavior.STATE\u HIDDEN
时,您可以在BottomSheetCallback
中执行任何您想要的操作
*顺便说一句,这意味着您不必在活动
中有协调布局
,也不必在布局中使用BottomSheetDialog
或BottomSheetDialogFragment
,尽管我不确定文档或其他开发人员资源中是否有明确的说明。我的主要活动rootView是与该行为协调或布局的产物。主要活动的根布局是什么?正如我在问题中所述,它是CoordinatorLayout。如果我在CoordinatorLayout中正确理解CoordinatorLayout?这很奇怪。当我在setupDialog()中添加getDialog().findViewById(R.id.design_bottom_sheet)并重新运行null时,正如您所提到的,当我在启动时调用它时,它起了作用。这是我的回答。谢谢。BottomSheetDialog
有点奇怪。它实际上并没有添加到您的协调器布局中。它全屏显示,背景透明,并在内部设置自己的坐标布局
,并将底页添加到其中。它还设置了自己的私有BottomSheetCallback
,您不能真正干预它。你能用BottomSheetBehavior
设置你自己的视图吗?事实上,现在我再次查看源代码,回调所做的唯一事情就是cancel()
在onStateChanged()
中的对话框
,如果newState==BottomSheetBehavior.STATE\u HIDDEN
,你可以在自己的回调中处理。如果您想试试,在BottomSheetDialog
上调用findViewById(R.id.design\u bottom\u sheet)
将获得具有BottomSheetBehavior
@MikeM的内部FrameLayout
。让我检查一下。不,特别是R.id.design\u bottom\u表
。它是BottomSheetDialog
中内部底部板材FrameLayout
的ID。它在设计库中定义。你不需要定义那个ID,谢谢。非常充分地利用。我想现在你可以发布答案了。完整而有用。