# Android 协调布局

总结来说: 协调布局CoordinatorLayout,协调AppBarLayout和一个滚动View,比如recyclerView、ScrollView, 让滚动的View在滚动的时候, AppBarLayout中中的子view做对应的响应, 对应下面五个属性。 滚动的View要加app:layout_behavior="@string/appbar_scrolling_view_behavior"属性, 如果出现滑动时闪烁等问题可以用https://github.com/yuruiyin/AppbarLayoutBehavior自定义的behavior解决。

CollapsingToolbarLayout做AppBarLayout的子view还可以实现视差滚动效果。

CoordinatorLayout + AppBarLayout + RecyclerView

CoordinatorLayout 是协调布局, 用来协调RecyclerView滚动时,AppBarLayout中子view如何滚动。 AppBarLayout的子view通过layout_scrollFlags属性来标识要怎么响应滚动。

layout_scrollFlags的属性

  • scroll :加上这个才能参与滚动,使用其他属性也必须要加上这个属性
  • enterAlways:先滚动toolbar
  • enterAlwaysCollapsed:要和scroll、enterAlways和最小高度一起使用,app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" android:minHeight="50dp",展开时先展开到最小高度, 最后才展开全部。
  • exitUntilCollapsed:要和scroll和最小高度一起使用,app:layout_scrollFlags="scroll|exitUntilCollapsed" android:minHeight="50dp",收缩时,收缩到最小高度。
  • snap: 要和scroll配合使用,app:layout_scrollFlags="scroll|snap", 展开或者收缩到一半, 会自动展开或收缩完。
  • snapMargins:必须和snap配合使用, 以margin的距离snap。

CollapsingToolbarLayout 折叠布局作为AppBarLayout的子布局,CollapsingToolbarLayout的子view可以设置三个属性来响应滚动。

  • off:不折叠
  • parallax:视差效果折叠
  • pin:折叠后固定 app:layout_collapseMode="parallax"

# AppBarLayout 折叠展开监听

binding.llHeader 是CollapsingToolbarLayout中pin属性的子view。 默认隐藏, 因为pin是固定显示的。


    private CollapsingToolbarLayoutState state;
    private enum CollapsingToolbarLayoutState {
        EXPANDED,
        COLLAPSED,
        INTERNEDIATE
    }
    
    
        binding.appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (verticalOffset == 0) {
                    if (state != CollapsingToolbarLayoutState.EXPANDED) {
                        state = CollapsingToolbarLayoutState.EXPANDED;//修改状态标记为展开
//                        binding.tvHeader.setText("EXPANDED");//设置title为EXPANDED
                    }
                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                    if (state != CollapsingToolbarLayoutState.COLLAPSED) {
//                        binding.tvHeader.setText("");//设置title不显示
                        binding.llHeader.setVisibility(View.VISIBLE);//隐藏播放按钮
                        state = CollapsingToolbarLayoutState.COLLAPSED;//修改状态标记为折叠
                    }
                } else {
                    if (state != CollapsingToolbarLayoutState.INTERNEDIATE) {
                        if(state == CollapsingToolbarLayoutState.COLLAPSED){
                            binding.llHeader.setVisibility(View.INVISIBLE);//由折叠变为中间状态时隐藏播放按钮
                        }
//                        binding.tvHeader.setText("INTERNEDIATE");//设置title为INTERNEDIATE
                        state = CollapsingToolbarLayoutState.INTERNEDIATE;//修改状态标记为中间
                    }
                }
            }
        });

    

# 应用场景

AppBarLayout 可以实现中的子view可以实现,完全视差收缩, 或视差收缩到指定的minHeight。 tablayout放在

去除AppBarLayout自带底部阴影

app:elevation="@dimen/dp0"

xml布局示例

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.google.android.material.appbar.AppBarLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:elevation="0dp">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="400dp"
                    android:background="#222222"
                    android:gravity="center"
                    android:minHeight="50dp"
                    android:text="该区域可折叠"
                    android:textColor="@android:color/white"
                    android:textSize="30sp"
                    app:layout_scrollFlags="scroll|exitUntilCollapsed" />
                <!--                app:layout_scrollFlags="scroll"-->

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:background="#DD012D"
                    android:gravity="center"
                    android:text="该区域为上滑至头部固定区域"
                    android:textColor="@android:color/white"
                    android:textSize="20sp" />
            </com.google.android.material.appbar.AppBarLayout>

            <androidx.core.widget.NestedScrollView
                android:id="@+id/rv_demo1_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#00ff00"
                    android:text="这是一个滚动布局"
                    android:textSize="200sp" />
            </androidx.core.widget.NestedScrollView>
        </androidx.coordinatorlayout.widget.CoordinatorLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="@color/blue"
            android:gravity="center"
            android:text="标题"
            android:textSize="24sp"></TextView>
    </RelativeLayout>

</layout>

Last Updated: 1/9/2024, 11:22:13 AM