最近将项目依赖进行了更新,将targetSdkVersion升至25(Android N 7.1),同时把design, appcompat......等同步升级至v25.0.1,于是AppBarLayout出现了点小问题,抱着遇见问题就要解决问题的态度,所以并没有采用降级旧版本的方法,于是有了以下记述。
1. AppBarLayout旧用法
AppBarLayout出现在design包里,拥有自带阴影,可与Coordinatorlayout联动等特性,用法也十分简单,只需要在xml里写好即可:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.AppBarLayout >
2. 新版问题
按照上述写法时,在新版本中有一个细微的改变:当切换至新页面时,AppBarLayout的底部阴影是延时出现的而不是原本已经存在的,这个时差导致切换的感觉有些别扭。同时,默认的阴影高度有些高,于是很自然的去写了旧版的用法。
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="2dp">
</android.support.design.widget.AppBarLayout >
然而发现阴影高度不仅没有变成2dp反而完全不见了。总结成以下两个问题:
- 阴影高度无法自定义;
- 阴影出现有延迟。
3. 新版变化
因为出现的两个问题都与阴影有关,自然而然想到了设置阴影的api——setTargetElevation()这个方法,查询源码的瞬间发现了问题的所在:
@Deprecated
public void setTargetElevation(float elevation) {
if (Build.VERSION.SDK_INT >= 21) {
ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, elevation);
}
}
@Deprecated
public float getTargetElevation() {return 0;}
关于阴影的api竟然已经被废弃了,get永远返回0,而set只有在sdk-21及以上才会生效,不过set方法中却为提供了新的线索:StateListAnimator。
4. 解决方法
既然新的AppBarLayout采用了属性动画来展示阴影,那么最简单的方式则是规规矩矩的设置一个属性动画。
创建一个执行时间1ms的动画:/animator/appbar_elevation.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<objectAnimator
android:duration="1"
android:propertyName="elevation"
android:valueTo="2dp"
android:valueType="floatType" />
</item>
</selector>
设置给AppBarLayout
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stateListAnimator="@animator/appbar_elevation">
</android.support.design.widget.AppBarLayout>
这种方式同样可以在代码里实现。
appBarLayout.setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), R.animator.appbar_elevation));
至此尚未完全解决,因为setStateListAnimator这个方法是21及以上才拥有的api。平常使用未曾探究低版本的兼容问题(项目最低支持至5.0),如果想要兼容低版本,可以在appbar里加阴影图片或者降级Library版本,嗯......若有更好的解决方式,请告知......