最近將項(xiàng)目依賴進(jìn)行了更新换可,將targetSdkVersion升至25(Android N 7.1)贸人,同時把design, appcompat......等同步升級至v25.0.1,于是AppBarLayout出現(xiàn)了點(diǎn)小問題募判,抱著遇見問題就要解決問題的態(tài)度爹凹,所以并沒有采用降級舊版本的方法,于是有了以下記述飒赃。
1. AppBarLayout舊用法
AppBarLayout出現(xiàn)在design包里,擁有自帶陰影科侈,可與Coordinatorlayout聯(lián)動等特性载佳,用法也十分簡單,只需要在xml里寫好即可:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.AppBarLayout >
2. 新版問題
按照上述寫法時臀栈,在新版本中有一個細(xì)微的改變:當(dāng)切換至新頁面時蔫慧,AppBarLayout的底部陰影是延時出現(xiàn)的而不是原本已經(jīng)存在的,這個時差導(dǎo)致切換的感覺有些別扭权薯。同時姑躲,默認(rèn)的陰影高度有些高,于是很自然的去寫了舊版的用法盟蚣。
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="2dp">
</android.support.design.widget.AppBarLayout >
然而發(fā)現(xiàn)陰影高度不僅沒有變成2dp反而完全不見了黍析。總結(jié)成以下兩個問題:
- 陰影高度無法自定義屎开;
- 陰影出現(xiàn)有延遲阐枣。
3. 新版變化
因?yàn)槌霈F(xiàn)的兩個問題都與陰影有關(guān),自然而然想到了設(shè)置陰影的api——setTargetElevation()這個方法奄抽,查詢源碼的瞬間發(fā)現(xiàn)了問題的所在:
@Deprecated
public void setTargetElevation(float elevation) {
if (Build.VERSION.SDK_INT >= 21) {
ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, elevation);
}
}
@Deprecated
public float getTargetElevation() {return 0;}
關(guān)于陰影的api竟然已經(jīng)被廢棄了蔼两,get永遠(yuǎn)返回0,而set只有在sdk-21及以上才會生效逞度,不過set方法中卻為提供了新的線索:StateListAnimator额划。
4. 解決方法
既然新的AppBarLayout采用了屬性動畫來展示陰影,那么最簡單的方式則是規(guī)規(guī)矩矩的設(shè)置一個屬性動畫第晰。
創(chuàng)建一個執(zhí)行時間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>
設(shè)置給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>
這種方式同樣可以在代碼里實(shí)現(xiàn)锁孟。
appBarLayout.setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), R.animator.appbar_elevation));
至此尚未完全解決彬祖,因?yàn)閟etStateListAnimator這個方法是21及以上才擁有的api茁瘦。平常使用未曾探究低版本的兼容問題(項(xiàng)目最低支持至5.0),如果想要兼容低版本储笑,可以在appbar里加陰影圖片或者降級Library版本甜熔,嗯......若有更好的解決方式,請告知......