Dynamically change height of BottomSheetBehavior

后端 未结 9 1058
既然无缘
既然无缘 2020-12-13 03:42

I\'m using the BottomSheetBehavior from Google recently released AppCompat v23.2. The height of my bottom sheet depends on the content displayed inside of the b

相关标签:
9条回答
  • 2020-12-13 04:15

    I've followed @HaraldUnander advice, and it gave me an idea which has actually worked. If you run a thread (couldn't make it work with the post method as him) after the BottomSheetBehavior.state is set up programmatically to STATE_COLLAPSED, then you can already obtain the height of your views and set the peekHeight depending on it's content.

    So first you set the BottomSheetBehavior:

    BottomSheetBehavior.from(routeCaptionBottomSheet).state = BottomSheetBehavior.STATE_COLLAPSED
    

    And then you set the peekHeight dynamically:

    thread {
        activity?.runOnUiThread {
            val dynamicHeight = yourContainerView.height
            BottomSheetBehavior.from(bottomSheetView).peekHeight = dynamicHeight
        }
    }
    

    If using Java (I'm using Kotlin with Anko for threads), this could do:

    new Thread(new Runnable() {
        public void run() {
            int dynamicHeight = yourContainerView.getHeight();
            BottomSheetBehavior.from(bottomSheetView).setPeekHeight(dynamicHeight);
        }
    }).start();
    
    0 讨论(0)
  • 2020-12-13 04:22

    I faced the same issue, when trying to update the peek height based on its contents, the height from a previous layout was found. This makes sense as the new layout had not taken place yet. By posting on the UI thread the layout height is calculated after the new layout, and another layout request is made to update the bottom sheet to the right height.

    void show() {
        setVisibility(View.VISIBLE);
        post(new Runnable() {
            @Override
            public void run() {
                mBottomSheetBehavior.setPeekHeight(findViewById(R.id.sheetPeek).getHeight());
                requestLayout();
            }
        })
    }
    
    0 讨论(0)
  • 2020-12-13 04:23

    Though the issue has been resolved in >=24.0.0 support library, if for some reason you still have to use the older version, here is a workaround.

    mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull final View bottomSheet, int newState) {
                bottomSheet.post(new Runnable() {
                    @Override
                    public void run() {
                        //workaround for the bottomsheet  bug
                        bottomSheet.requestLayout();
                        bottomSheet.invalidate();
                    }
                });
            }
    
            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            }
        });
    
    0 讨论(0)
  • 2020-12-13 04:25

    You can use BottomSheetBehavior#setPeekHeight for that.

    FrameLayout bottomSheet = (FrameLayout) findViewById(R.id.bottom_sheet);
    BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);
    behavior.setPeekHeight(newHeight);
    

    This does not automatically move the bottom sheet to the peek height. You can call BottomSheetBehavior#setState to adjust your bottom sheet to the new peek height.

    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
    
    0 讨论(0)
  • 2020-12-13 04:28

    Below code snippet helped me solve this issue where i am toggling between visibility of different views in layout and height is automatically changing for my bottom sheet.

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.your_bottom_sheet_layout, container, false)
    }
    
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
        dialog.setContentView(R.layout.your_bottom_sheet_layout)
    
        dialog.setOnShowListener {
            val castDialog = it as BottomSheetDialog
            val bottomSheet = castDialog.findViewById<View?>(R.id.design_bottom_sheet)
            val behavior = BottomSheetBehavior.from(bottomSheet)
            behavior.state = BottomSheetBehavior.STATE_EXPANDED
            behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                        behavior.state = BottomSheetBehavior.STATE_EXPANDED
                    }
                }
    
                override fun onSlide(bottomSheet: View, slideOffset: Float) {}
            })
        }
    
        return dialog
    }
    
    0 讨论(0)
  • 2020-12-13 04:31

    I was facing the same issue when I used a recyclerview inside a BottomSheet and the items changed dynamically. As @sosite has mentioned in his comment, the issue is logged and they have fixed it in the latest release. Issue log here

    Just update your design support library to version 24.0.0 and check.

    0 讨论(0)
提交回复
热议问题