Android Bottomsheet TextView 高度在第一次展开时未调整

Android Bottomsheet TextView height not adjusted on first time expanding

TL;DR: Bottomsheet 中的 TextView 第一次 Bottomsheet 展开时未显示换行的多行文本,但在折叠后会自行调整。

所以我正在使用 design-23.2.1 库中的 Bottomsheet。

我的布局文件如下所示:

<android.support.design.widget.CoordinatorLayout>

    ......

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior"/>
</android.support.design.widget.CoordinatorLayout>

Bottomsheet的内容基本上是一个列表:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView 
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:singleLine="false" />
    ...
</LinearLayout>

问题是每当 Bottomsheet 设置为 STATE_EXPANDED 第一次 时,TextView 是单行且文本被换行, 并且行尾没有省略号 .

那么设置成STATE_COLLAPSED后,TextView的高度就可以了,多行也很合适

我知道设置为 STATE_COLLAPSED 后会发生高度重新布局,因为我将它从折叠中滑出并且多线已经存在。

提供了解决方法 here。我跟着它添加了这个:

bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        if (newState == BottomSheetBehavior.STATE_EXPANDED) {
            bottomSheetBehavior.onLayoutChild(coordinatorLayout,
                                            bottomSheetView,
                                            ViewCompat.LAYOUT_DIRECTION_LTR);
        }
    }
    ........
}

确实在第一次展开Bottomsheet时重新调整了高度。然而它是在展开动画完成后突然发生的。

有没有办法像Google Map 一样在展开动画之前调整高度?

更新

我发现这个问题是因为我在展开前把Bottomsheet设置成了STATE_COLLAPSED。如果没有设置,那么问题就消失了,第一次就正确调整了高度。

现在我的问题是:为什么在扩展前将其设置为 STATE_COLLAPSED 会导致该问题?

切换到设计库24.0.0后,问题无法复现。

感谢Android团队的努力,让我们的生活越来越轻松。

如果出于某种原因您仍然必须使用旧的支持库,这里是解决方法。

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) {
        }
    });