目录
豆瓣效果
分析思路
- 首先可以看到顶部有一个2种样式的悬浮bar
并且详情部分内容可以折叠
实现效果就应该是 appbarlayout+CollapsingToolbarLayout + Toolbar可以实现 - 中间的内容应该是普通的recycleView
- 关于影评栏,通过截图发现他的影评栏实现 应该是2个对象,A对象直接跟随在滚动内容的下方,另外一个对象B作为1个浮层,吸附在底部,当A跟随内容上移出现是,B隐藏。
在一加6的流海全面屏下,可以看到,豆瓣的处理A对象展现高度的时候,没有处理好。 - 影评栏的双重吸顶效果
因为顶部使用了appbarlayout,所以这里的效果可以使用behavior属性来实现
app:layout_behavior="@string/appbar_scrolling_view_behavior"
- 最后是悬浮在底部的对象B,
- 它要能支持底部的手势滑出/收缩
- 可以支持完全隐藏。
- 本来想用抽屉实现,但是搜了一下,google自带的behavior基本上实现了各种抽屉效果,所以才用BottomSheetBehavior实现。
关于BottomSheetBehavior
BottomSheetBehavior官方文档
Material Design官方文档Sheets: bottom的介绍
BottomSheetBehavior 是个底部动作条的意思 , 可以设置最小高度和最大高度 ,执行进入/退出动画,响应拖动/滑动手势等,配合coordinatorlayout+appbarlayout就可以实现目标效果
Tips 在AndroidX之前 BottomSheetBehavior的路径是:
android.support.design.widget.BottomSheetBehavior
AndroidX之后路径更改为:
com.google.android.material.bottomsheet.BottomSheetBehavior
动手实现
布局
大概写一下布局层级,详细代码见demo
<coordinatorlayout>
<AppBarLayout>
<CollapsingToolbarLayout>
<RecyclerView/>
<Toolbar>
<LinearLayout>
...
</LinearLayout>
</Toolbar>
</CollapsingToolbarLayout>
</AppBarLayout>
<FrameLayout
android:id="@+id/fl_body"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
...
</FrameLayout>
<FrameLayout
android:id="@+id/fl_bottom"
app:layout_behavior="@string/bottom_sheet_behavior">
...
</FrameLayout
</coordinatorlayout>
BottomSheetBehavior 使用类似于appbarlayout 必须是CoordinatorLayout 直接子View,
CoordinatorLayout可以处理子View只有中各种嵌套滑动事件,自带了2个layout_behavior,这里都用上了。
BottomSheetBehavior 本身又附加的属性 比如
app:behavior_hideable //设置为true表示底部弹出框可隐藏
app:behavior_peekHeight //窥视高度 , 就是BottomSheet折叠后的最小显示高度
app:behavior_skipCollapsed //如果app:behavior_hideable设置为true,并且behavior_skipCollapsed设置为true , 则它没有折叠状态。
Activity
首先关键对象:
private BottomSheetBehavior mBottomSheetBehavior
BottomSheetBehavior 的获取
mBottomSheetBehavior = ViewPagerBottomSheetBehavior.from(fl_bottom);//取得对象
mBottomSheetBehavior.setHideable(false);//设置不可隐藏
mBottomSheetBehavior.setState(ViewPagerBottomSheetBehavior.STATE_HIDDEN);//设置折叠
使用tablayout+ViewPager +Fragment 来实现影评栏的内容
剩下填充数据代码略,详见demo
运行效果:
大体样子出来了,还有几个细节一点一点处理:
- 顶部bar的变化
- BottomSheetBehavior 高度
- bottom右边的fragment不能响应滑动事件
- 当body数据出现时要隐藏BottomSheetBehavior
顶部bar根据高度变化
顶部滚动内容是 Recycleview ,Recycleview在CollapsingToolbarLayout中会被全部加载,所以无法监听Recycleview的滚动
这里提供一种思路,监听appbarlayout的滚动,对toolbar样式改变
toolbar = findViewById(R.id.toolbar);
ll_topbar = findViewById(R.id.ll_topbar);
ll_topbar.getBackground().mutate().setAlpha(0);
final float headerTopHeight = 500;
appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
//i 当前appbarlayout 已经向下滚动了多少高度
Log.e("wanghe","onOffsetChanged "+i);
if (-i < headerTopHeight) {
float fix = (-i) / headerTopHeight;
ll_topbar.getBackground().mutate().setAlpha((