Android Support Library 23.2

qrgs8398 8年前

来自: http://blog.chengyunfeng.com/?p=869

本周 Android Support 库发布了 23.2新版本,该版本包含了几个新功能。

支持 Vector Drawables 和 Animated Vector Drawables

使用矢量图的好处之一就是不用出多个图片(hdpi, xhdpi 等)了, 只需要一个矢量图即可涵盖所有屏幕密度的需要。矢量图在 Android 5.0 才开始支持,使用 23.2 support 库中的 support-vector-drawable 和 animated-vector-drawable 可以在之前的版本支持矢量图了。之前Android studio 在 build 的时候, 通过 生成 PNG 图片来支持矢量图 ,要使用 23.2 版本中的矢量图功能,需要禁用之前版本的功能。如果你使用的 gradle 插件为 2.0+ 版本,则通过如下方式来启用新功能:

Java

// Gradle Plugin 2.0+     android {       defaultConfig {         vectorDrawables.useSupportLibrary = true        }     }
 // Gradle Plugin 2.0+     android {      defaultConfig {        vectorDrawables.useSupportLibrary = true        }     }  
</div>

如果你使用 1.5 的 gradle 插件,则需要通过如下的方式:

Java

// Gradle Plugin 1.5     android {       defaultConfig {         generatedDensities = []      }        // This is handled for you by the 2.0+ Gradle Plugin      aaptOptions {        additionalParameters "--no-version-vectors"      }     }
// Gradle Plugin 1.5     android {      defaultConfig {        generatedDensities = []      }         // This is handled for you by the 2.0+ Gradle Plugin      aaptOptions {        additionalParameters "--no-version-vectors"      }     }  
</div>

然后就可以使用 VectorDrawableCompat 和 AnimatedVectorDrawableCompat 了,VectorDrawableCompat 最低可以在 API 7 版本上使用, 而 AnimatedVectorDrawableCompat 需要 API 11 版本。目前通过 AppCompat 库只支持 ImageView 和其子类(例如 ImageButton 和 FloatingActionButton)可以在布局文件中直接使用 矢量图,支持方式为使用 app:srcCompat 来替代 android:src,

XHTML

<ImageView      android:layout_width="wrap_content"      android:layout_height="wrap_content"      app:srcCompat="@drawable/ic_add" />
<ImageView      android:layout_width="wrap_content"      android:layout_height="wrap_content"      app:srcCompat="@drawable/ic_add"/>  
</div>

如果在代码中设置矢量图,则和之前一样,可以直接使用 setImageResource() 。使用 AppCompat 和 app:srcCompat 是使用矢量图最简单的方式。

在5.0之前的版本除了 app:srcCompat 属性之外,其他属性都不支持矢量图,例如 TextView 的 android:drawableLeft ,你如果在该属性上使用矢量图,则在5.0之前的版本上会crash。但是,你如果把矢量图放到其他 Drawable 容器中,再使用这个 Drawable 容器可以支持5.0之前的版本,支持的容器有 StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable, 和 RotateDrawable。

你可以在 Drawable 容器中应用你的矢量图,例如通过 StateListDrawable 来引用矢量图,然后在 TextView 的 android:drawableLeft 中使用这个 StateListDrawable,这样在 5.0 之前的版本也可以使用矢量图了。

这样每个矢量图都需要放到一个 Drawable 容器中,可能比较繁琐,如果你使用 Data Binding 框架,则还可以又一个相对方便的方式。

定义一个 BindingAdapter, 该 BindingAdapter 把一个Drawable id 绑定到 TextView 的 drawableTop,

Java

public class Bindings {        @BindingAdapter({"bind:topId"})      public static void loadImage(TextView view, int topResId) {          view.setCompoundDrawablesWithIntrinsicBounds(0,topResId, 0,0);        }  }
public class Bindings {         @BindingAdapter({"bind:topId"})      public static void loadImage(TextViewview, int topResId) {          view.setCompoundDrawablesWithIntrinsicBounds(0,topResId, 0,0);         }  }
</div>

然后在 布局文件中,使用这个自定义的 BindingAdapter,

XHTML

<?xml version="1.0" encoding="utf-8"?>  <layout  xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:bind="http://schemas.android.com/apk/res-auto">      <data>          <import type="org.goodev.myapplication.R" />      </data>          <TextView              android:layout_width="wrap_content"              android:layout_height="wrap_content"              bind:topId="@{R.drawable.ic_favorite_outline_24dp}"              android:text="Hello World!" />  </layout>
<?xmlversion="1.0" encoding="utf-8"?>  <layout  xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:bind="http://schemas.android.com/apk/res-auto">      <data>          <importtype="org.goodev.myapplication.R"/>      </data>          <TextView              android:layout_width="wrap_content"              android:layout_height="wrap_content"              bind:topId="@{R.drawable.ic_favorite_outline_24dp}"              android:text="Hello World!"/>  </layout>
</div>

AppCompat DayNight 主题

除了支持矢量图以外,23.2版本中还保护了一个新的 Theme.AppCompat.DayNight主题。

在 API 14之前的版本,DayNight 主题和其子主题 ( DayNight.NoActionBar, DayNight.DarkActionBar, DayNight.Dialog 等) 都使用 白色主题替代。在 14+版本,则 DayNight 可以使应用很容易的同时支持白色和黑色主题,并且可以根据用户当前的时间自动切换主题,白天使用白色主题,夜晚使用黑色主题,是不是很酷。

默认情况下系统使用 UiModeManager.getNightMode() 来判断是否使用黑色主题。在 AppCompatDelegate 中可以重写该方法。通过函数 AppCompatDelegate.setDefaultNightMode() 可以设置整个应用的模式,也可以通过 getDelegate().setLocalNightMode() 函数来修改当前 Activity 和 Dialog 的主题。

如果使用 AppCompatDelegate.MODE_NIGHT_AUTO 模式,系统会根据当前的时间和设备最后已知的位置(需要您的应用具有位置权限)来自动切换主题。

如果你使用了 DayNight ,请全面测试你的应用在每个主题都可以使用,特别是文本和图标的颜色,如果你使用标准的 TextAppearance.AppCompat 来设置文字样式,或者从 android:textColorPrimary 来获取颜色,则系统会自动切换到合适的颜色。

除了这两个比较大的新功能以外,23.2 版本中还有如下改动,详细情况请 参考这里

  • Design 库中新加一个 bottom sheet 控件。

  • Support v4 的 MediaBrowserServiceCompat

  • RecyclerView 的自动计算本身大小的功能,这样 RecyclerView 就可以根据其内容的大小来设置自己的尺寸了。

  • Custom Tabs 更加好用。

  • Leanback for Android TV 中新的 GuidedStepFragment ,更加方便的创建新手指引。

</div>