htpps://rainmonth.github.io/posts/A180305.html
摘要
本文主要介绍android.support.design.widget包下的一些Material Design控件,很多市场上绚丽的App的实现都是基于这些库的,Android本身为我们封装出来的效果就足够平常使用了,下面我讲分别详细介绍各个MD控件,同时自己会做一些扩展,本文先大体介绍一下各个控件,然后详细介绍CoordinatorLayout控件。
系列文章参考:
- CoordinatorLayout
- AppBarLayout介绍
- SwipeRefreshLayout
- CardView
- CollapsingToolbarLayout
- FloatingActionButton
[toc]
CoordinatorLayout
使用场景
- 作为顶层容器;
- 作为协调子View交互的容器;
注意事项
- 通过为子View指定Behavior,CoordinatorLayout可以让在同一个父容器的子View之间有许多不同种类的交互(子View之间、子View和父View之间),CoordinatorLayout的子View可以指定默认的Behavior
- Behavior可以用来实现不同的交互和附加的布局改动效果;
- 可以通过设置
CoordinatorLayout.LayoutParams#setAnchorId(int)
来实现浮动相关效果; - 可以通过设置
`CoordinatorLayout.LayoutParams#insetEdge
参数来控制子View插入CoordinatorLayout的方式
AppBarLayout
AppBarLayout
继承自LinearLayout,但他实现了很多Material Design中App Bar概念中的功能,其中的代表就是手势滑动。
- AppBarLayout的子View必需声明其滚动的行为(通过
setScrollFlags(int)
方法或’app:layout_scrollFlags’属性); - AppBarLayout通常是配合CoordinatorLayout来使用的,并且是其直接子View,如果其父类不是CoordinatorLayout,那么其很多特性就发挥不出来;
- AppBarLayout通常还需要一个同级的滚动控件(即兄弟控件),这样就能知道AppBarLayout需要在什么时机配合滚动了。
layout_scrollFlags属性解释
上面说了,AppBarLayout的子View必须设置layout_scrollFlags
属性,否则其很多特性就不能发挥作用了,那么这个属性到底有什么作用呢。这个属性共有以下5种值:
1 | SCROLL_FLAG_SCROLL, |
下面分别对这五种属性作说明:
SCROLL_FLAG_SCROLL
,对应于属性scroll
,表示伴随着滚动事件滚出或滚进屏幕;- 该值是其他四种值生效的前提,及其他四个值如果要生效,必须设置这个值;
- 如果设置了该属性的子View前面有没有设置该属性的统计View,那么AppBarLayout其他设置了改属性的子View都无效
SCROLL_FLAG_ENTER_ALWAYS
,对应于属性enterAlways
,在和scroll
一起使用时,当发生向下滚动事件时,设置了该属性的子View会优先于SrollView先进入屏幕;SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
,对应于enterAlwaysCollapsed
,是enterAlways
的附加值。当子View设置的layout_scrollFlags
属性值为scroll|enterAlways|enterAlwaysCollapsed
时,如果子View设置了最小高度minHeight
,那么当发生向下滚动的事件时,子View会先滚动,知道达到最小高度,达到后,ScrollView会滚动知道滚动完毕,然后子View在滚动剩余的高度。SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
,对应于exitUntilCollapsed
,同样和最小高度有关,当向上滑动的事件发生时,设置该属性的子View会先向上滚动至最小高度,然后保持高度不变,然后ScrollView再开始滚动。SCROLL_FLAG_SNAP
,对应于snap
属性,即ChildView的滚动吸附效果,设置了该值后,ChildView不会存在局部显示的情况,要么全部滚进屏幕,要么全部滚出屏幕。
总结下:scroll
就是子View后滚,enterAlways
就是子View先滚,enterAlwaysCollapsed
就是子View先滚到折叠状态然后ScrollView再滚,完成后子View在滚,exitUntilCollapsed
,子View滚到到折叠态后就不在滚了,开始管ScrollView,snap
指的是吸附滚动,要么全部显示,要么全部隐藏。
最终保留的高度
这个最终保留高度其实是针对layout_scrollFlags
为exitUntilCollapsed
和enterAlwaysCollapsed
的,当layout_scrollFlags
设置成了上面两个值时,前者在子View滑动达到最小高度后子View就不在滚动,这个就是最终保留高度
。
android.support.v7.Toolbar
Toolbar为我们顶部导航栏的开发带来了许多便利,但如果使用不注意也会有很多坑。
便利
可以只将Toolbar当做一个容器,它本身就是继承自ViewGroup的,然后在里面定义自己的顶部导航栏布局
在没有ActionBar的AppCompatActivity中,可以通过setSupportActionBar(Toolbar)来设置ActionBar,然后使用ActionBar的一些功能。
注意:这里必须是没有ActionBar的AppCompatActivity,否则会报如下错误:
1
Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
坑
Toolbar元素间距调整麻烦
直接使用Toolbar或由它初始化的ActionBar时,UI上的定制性比较差,Toolbar主要包含以下几个元素(按从左到右的顺序):
- NavigationIcon,导航图标,默认为向左箭头,可以自己设置;
- Logo,当前页面对应的Logo,国内很少使用这个属性;
- 标题,有两种标题
- Title,页面标题,常用;
- SubTitle,页面子标题,较常用;
- Menu,页面右边对应的菜单;
说UI的定制,主要就是前面1、2、3三个元素之间的间距调整,在V22之前,由于不存在contentInsetStartWithNavigation
属性,1和3的间距还可以接受,但V22之后,添加了这个属性,会发现1和3的间距太大了,解决方法就是设置给属性的值为0dp,设置完成后发现NavigationIcon与Title的距离还是太大了,这是因为NavigationIcon是存在padding值得,那么如何搞定这个padding值呢,我们可以通过AppTheme的如下属性来设置:
<item name="toolbarNavigationButtonStyle">@style/myToolbarNavigationButtonStyle</item>
其中myToolbarNavigationButtonStyle
定义如下:
1 | <style name="myToolbarNavigationButtonStyle" parent="@style/Widget.AppCompat.Toolbar.Button.Navigation"> |
通过上面的padding可以实现NavigationIcon相关的属性定制。
ActionBar方法调用存在限制
一定要先调用setSupportActionBar
这个方法之后然后在调用ActionBar的相关方法