# 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>