Android支持BottomSheetBehavior不能动态吗?

时间:2016-03-25 11:37:03

标签: android xml android-layout bottom-sheet

我正在使用Android支持库中的Bottom Sheet,如下所示:

XML:

<LinearLayout
    android:id="@+id/bottomSheetLinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/fourth_white"
    android:orientation="vertical"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior" />

我将子视图添加到LinearLayout:

bottomSheet.addView(actionButtonView);

在我添加完子视图后,我初始化BottomSheetBehavior并展开它:

BottomSheetBehavior sheetBehavior = BottomSheetBehavior.from(bottomSheet);
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

这不起作用。没有任何表现。即使我在XML中预设LinearLayout高度,它也只是白色。

如果我在XML中添加LinearLayout中的所有子视图,那么一切正常。当我尝试以编程方式动态添加视图时,它无法正常工作。

任何人都有类似的问题吗?

2 个答案:

答案 0 :(得分:2)

与BottomSheetBehavior上的动态内容相关的问题与实现它的扩展大小计算有关。 BottomSheetBehavior在onLayoutChild方法中计算扩展大小。但是当您更改工作表布局的内容时,进程异步启动。即使你调用RequestLayout或类似的东西。因此调用的后果是这样的:

  1. BottomSheetBehavior具有旧的扩展大小(在您的情况下,我认为它是零)
  2. 您向BottomSheet添加内容。扩大规模仍旧。
  3. 您将SetState调用为EXPANDED。 BottomSheetBehavior仍然记得旧的扩展大小并将动画启动到该大小。州改为STATE_SETTLING!
  4. onLayoutChild调用,BottomSheetBehavior计算新的扩展大小。但是动画已经在进行中且状态为STATE_SETTLING,因此BottomSheetBehavior不会改变其大小
  5. 动画完成。 BottomSheet的大小是旧的。州改为EXPANDED,但BottomSheetBehavior&#34;忘了&#34;扩展的大小在动画期间发生了变化。
  6. 这肯定是BottomSheetBehaviour实施的错误。

    在我的项目中,我发现了这样的解决方法:

    private void showPanel(final View panelContent) {
        if (panelBehavior.getState()!=BottomSheetBehavior.STATE_EXPANDED) {
            panelBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                @Override
                public void onStateChanged(final View bottomSheet, int newState) {
                    if (newState==BottomSheetBehavior.STATE_EXPANDED) {
                        panelBehavior.setBottomSheetCallback(null);
                        contentView.removeAllViews();
                        contentView.addView(panelContent);
                        panelView.setVisibility(View.VISIBLE);
    
                    }
                }
    
                @Override
                public void onSlide(View bottomSheet, float slideOffset) {
    
                }
            });
            panelBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            return;
        }
        contentView.removeAllViews();
        contentView.addView(panelContent);
        panelView.setVisibility(View.VISIBLE);
    }
    
    private void hidePanel() {
        panelBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        panelView.setVisibility(View.GONE);
        contentView.removeAllViews();
    }
    

    因此,当您需要显示带有新内容的BottomSheet时,请调用ShowPanel。当你需要完全隐藏BottomSheet调用hidePanel时(如果你需要在项目中隐藏它。如果不是,你可以从方法中删除setVisibility)。

    解决方法的想法是,当BottomSheetBehavior未处于展开状态时,永远不要更改BottomSheet的内容。如果未展开状态,只需将其更改为展开状态,等待动画结束,然后再更改内容。

答案 1 :(得分:1)

尝试发布runnable以查看消息队列:

bottomSheet.post(new Runnable() {
    @Override
    public void run() {
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    }
});

或者使用retrolambda:

bottomSheet.post(() -> bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED));