可以采用google提供的AppBarLayout实现此功能,接下来直接看效果图,看完效果图在说如何实现这几种效果。
效果一:这种是默认的最简单的,但应用中一般不实用
效果二:这种是没有title的滑动悬浮操作栏
效果三:带有自定义的title栏,滑动悬浮操作栏,这种开发中最常见
先引入design依赖库:
implementation 'com.android.support:design:29.0.3'
关于三个主要类的使用API查看:
关于AppBarLayout的api
关于CollapsingToolbarLayout的api
关于Toolbar的api
效果一主要是使用xml就可以实现,代码不需要做什么特殊处理,直接上代码:
一、从xml的布局结构可以看出层次关系
CoordinatorLayout
-AppBarLayout
-CollapsingToolbarLayout
-ImageView
-Toolbar
-NestedScrollView
要想实现折叠效果,所有布局都需要包裹在CoordinatorLayout布局之内,
AppBarLayout:可以容纳虚浮操作栏的布局
CollapsingToolbarLayout:此布局内的控件是可折叠的布局,Toolbar是默认的title栏,ImageView是可折叠布局,这里可以使用
ViewGroup
NestedScrollView:这个是外部可滑动的布局
接下来需要注意几个控件中的属性(这些属性你可以自己修改这试下):
1、Toolbar的layout_collapseMode属性有两种状态:
(1)、 pin:有该标志位的View在页面滚动的过程中会一直停留在顶部,比如Toolbar被固定在顶部
(2)、parallax:有该标志位的View表示能和页面同时滚动。
2、AppBarLayout是一个继承与LinearLayout,布局方式为垂直布局的一个组件,通常与CoordinatortLayout配合使用,如果放在其他ViewGroup中单独使用,那将起不到任何效果。AppBarLayout子View中设置app:layout_scrollFlags可设置执行的动作,分别有一下4个属性
(1) scroll:值设为scroll的View会跟随滚动事件一起发生移动。
(2) enterAlways:值设为enterAlways的View,当ScrollView往下滚动时,该View会直接往下滚动。而不用考虑ScrollView是否在滚动。
(3) exitUntilCollapsed:值设为exitUntilCollapsed的View,当这个View要往上逐渐“消逝”时,会一直往上滑动,直到剩下的的高度达到它的最小高度后,再响应ScrollView的内部滑动事件。
(4) enterAlwaysCollapsed:是enterAlways的附加选项,一般跟enterAlways一起使用,它是指,View在往下“出现”的时候,首先是enterAlways效果,当View的高度达到最小高度时,View就暂时不去往下滚动,直到ScrollView滑动到顶部不再滑动时,View再继续往下滑动,直到滑到View的顶部结束。
3、注意在NestedScrollView控件中添加了下面的属性,必须添加此属性,否则无法看到效果
app:layout_behavior="@string/appbar_scrolling_view_behavior"
二、看完xml布局,再来讲几个在activity中设置相关的代码,更能多的可以查看上面的各类的api使用
关于返回按钮的设置:
//设置自定义的返回按钮
mBinding.toolbar.setNavigationIcon(getResources().getDrawable(R.mipmap.ic_back));
//设置默认的返回按钮
// setSupportActionBar(mBinding.toolbar);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
关于CollapsingToolbarLayout的设置:
mBinding.ctlTitle.setCollapsedTitleGravity(Gravity.LEFT);//设置收缩后标题的位置
mBinding.ctlTitle.setExpandedTitleGravity(Gravity.BOTTOM);////设置展开后标题的位置
mBinding.ctlTitle.setTitle("Snowzhao");//设置标题的名字
mBinding.ctlTitle.setExpandedTitleMarginStart(10);//设置标题展开距离开始的距离
mBinding.ctlTitle.setExpandedTitleColor(Color.WHITE);//设置展开后标题的颜色
mBinding.ctlTitle.setCollapsedTitleTextColor(Color.RED);//设置收缩后标题的颜色
后面两个效果是在效果一的基础上修改的,就不细讲了,主要看有区别的地方:
从上面xml可以看出布局层级是:
CoordinatorLayout
-AppBarLayout
-CollapsingToolbarLayout
-LinearLayout 可折叠的布局
-ImageView
-TextView
-LinearLayout 虚浮的布局
-TextView
-RelativeLayout
-NestedScrollView
此中效果是没有title的,所以没有看到Toolbar类,但在AppBarLayout布局内多了一个LinearLayout可悬浮的布局,至于属性和效果一类似,没有特别的,Activity中也没有任何的代码
先看上面的xml的布局层级:
CoordinatorLayout
-AppBarLayout
-CollapsingToolbarLayout
-LinearLayout 折叠布局
-Toolbar
-RelativeLayout 自定义title布局
-LinearLayout 滚动悬浮布局
-NestedScrollView 外部滑动布局
看到此布局比效果二多了一个自定义title布局,而自定义title布局正好是在Toolbar布局中设置的。
注意:Toolbar布局中多了一个contentInsetStart,默认不设置会发现布局整体偏右了点。
app:contentInsetStart=“0dp”
关于滑动监听代码,可以看下面代码:
mBinding.appbarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
int totalScrollRange = appBarLayout.getTotalScrollRange();
Log.e("snow_app", "==totalScrollRange===" + totalScrollRange);
Log.e("snow_app", "=滑动=verticalOffset===" + verticalOffset);
///折叠区域(0,0)坐标在屏幕的位置verticalOffset值为负值 折叠区域的总高度totalScrollRange值为正值
//根据滑动距离和折叠区的总距离计算透明度
int color = changeAlpha(getResources().getColor(R.color.white), Math.abs(verticalOffset * 1.0f) / totalScrollRange);
mBinding.toolbar.setBackgroundColor(color);
});
好了基本使用就这样了,要想做类似TabLayout和ViewPager配合使用的功能,只需将TabLayout布局放在悬浮操作栏位置即可实现,感觉有用给个赞呗!
Demo地址