Android Support Library 23.1的变化
原文 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1025/3622.ht
这篇文章只说说那些我关注的变化,完整文档请看官网: http://android-developers.blogspot.com/2015/10/android-support-library-231.html
优化升级
RecyclerView的改变
这个版本最大的变化是动画系统。使用 ItemAnimator 的 canReuseUpdatedViewHolder() 方法,你可以重用已存在的 ViewHolder ,启动item内容动画支持。新的 ItemHolderInfo 与相关的api让ItemAnimator可以更灵活的在layout生命周期的正确时间收集想要的任何数据,把这些信息传给animate callback。
注意这个新的api并不是向后兼容的。如果你之前实现了一个ItemAnimator,你可以转而继承 SimpleItemAnimator ,,它提供了用新api封装了的旧api。你会发现ItemAnimator的有些方法完全被移除了。比如,如果你调用recyclerView.getItemAnimator().setSupportsChangeAnimations(false),你会发现这句代码不能再被编译了。你可以把它替换成:
ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); }
NavigationView开始支持自定义菜单
NavigationView 提供了创建一个抽屉导航(navigation drawer)的简便方法,比如可以使用xml文件来创建菜单项。现在有了更新的扩展,能够使用app:actionLayout 或者 MenuItemCompat.setActionView() 来为item设置自定义view。
bug修正
下面这两个bug在第一个版本就不该存在。
修正了TabLayout的bug
在23.1.0之前的版本中,TabLayout有一个致命的错误,虽然从外观上看起来不明显,但是对手势的体验影响较大。
当tab的选项卡每项的宽度不一致的时候,下划线的动画效果有时候会出现抖动行为。这种行为在由较宽的选项卡到较窄的选项卡过渡的时候比较容易发生。
下图演示了com.android.support:design:22.2.0版本下TabLayout的表现:
可以看出的确有抖动的行为,而且这还不是最明显的。当然在每个tab的宽度相差不大的情况下不是那么明显。
而23.1.0版本已经完美的修正了这个问题,下图是23.1.0版本TabLayout的表现:
gif的质量可能有点影响效果,但是实际的表现完全是流畅无比的。
AppBarLayout子view的滚动问题
当AppBarLayout子view设置了 app:layout_scrollFlags的时候,比如下面的代码在Toolbar上设置了app:layout_scrollFlags="scroll|enterAlways",随着相关视图(RecyclerView,或者NestedScrollView)的滚动,
Toolbar可能会出现只隐藏部分的情况,其实这个影响不大Toolbar本身高度有限。
<android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_scrollFlags="scroll|enterAlways" /> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="scrollable" style="@style/MyCustomTabLayout" /> </android.support.design.widget.AppBarLayout>
但是如果是想实现有头部图片的视差效果,比如类似下面的代码:
<android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="@dimen/detail_backdrop_height" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginStart="48dp" app:expandedTitleMarginEnd="64dp"> <ImageView android:id="@+id/backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:fitsSystemWindows="true" app:layout_collapseMode="parallax" /> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_collapseMode="pin" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout>
就会出现如图中的问题
可以看到,当我向上滑动的时候,要上划两次才完全隐藏图片。
这造成一种不流畅的感觉。
严格说来这不算是一种bug,而是支持库的作者有意为之,因为CoordinatorLayout所做的事情全都是根据某个滚动视图的滚动距离设置相关视图的位移。
但是这不光体验不好,还不符合材料设计的规范。
因此有很多人提出来,在23.1.0版本,为了解决这个问题,layout_scrollFlags新增了一个flag,叫做SCROLL_FLAG_SNAP。
用法如下:
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
其实就是加了个snap标志。
它可以确保滚动的时候AppBarLayout子view要么不显示要么显示完。
听起来很美好,但是用了才知道并不完美。
我自身的体验是,这更加增大了操作难度,很多次我上划无法滚上去,也有很多次下划无法滚下来。
其实我个人认为,正确的做法是,当用户的滑动速度到了一定大小(这代表滑动力度),只要上划就一定隐藏图片,只要下滑就一定显示完图片。
这些问题在第一个版本就该解决,因为第三方已经早就有人实现了自己的方案了,而chrisbanes却挖了无数个坑。这是带领开发者一起跳么。
不过有一点值得肯定,那就是现在AppBarLayout允许用户从AppBarLayout的那部分就开始滚动,而不是必须在滚动视图里。可以添加 DragCallback 来控制这个行为。