写在前面的几句话

前几天谷歌发布了android-support-library-23.2支持库,这一次23.2版本增加了一些新的支持库以及新的功能。接下来这篇文章,就是对这些新功能部分做简单的用法介绍

这次更新增加的东西有:

  • Support Vector Drawables and Animated Vector Drawables
  • AppCompat DayNight theme
  • Design Support Library: Bottom Sheets
  • Support v4: MediaBrowserServiceCompat
  • RecyclerView
  • Custom Tabs
  • Leanback for Android TV

需要添加的依赖如下:

compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.android.support:design:23.2.0'
compile 'com.android.support:support-vector-drawable:23.2.0'
compile 'com.android.support:animated-vector-drawable:23.2.0'

分别说明使用方法

1.Support Vector Drawables and Animated Vector Drawables(支持矢量图片和矢量图片动画)

其实前面的文章关于Metarial Design动画中也有介绍到矢量图与矢量图的动画,但是那是局限于5.0以上的设备才可以使用,没想到这么快就Support包就向下支持了,其实使用方法也很类似,大家可以参考下那篇文章,

想在低版本使用还需要做点东西:

AndroidStudio1.4已经引入过矢量绘图支持在构建时生成PNG图像。要想禁用此功能(并想使用最新支持库),你需要在你的build.gradle里面添加vectorDrawables.useSupportLibrary = true

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

你会发现这个新的属性只在AndroidStudio2.0版本存在。如果您使用的是AndroidStudio1.5,需要

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

通常需要在三个xml文件中定义可动的矢量图:

一个矢量图使用<vector>元素,放在res/drawable/下。

一个可动的矢量图使用<animated-vector>元素,放在res/drawable/下。

一个或更多个动画对象使用<objectAnimator>元素,放在res/anim/下。

可动矢量图可以使用<group>和<path>元素。<group>元素定义一系列路径或者子组,<path>元素定义可绘图的路径。

当你定义了一个想要作用动画的矢量可绘制图,使用android:name属性给每个group和path指定一个唯一的名字,这样你可以从动画的定义中找到他们。

res/drawable/vector_drawable_cpu_ani.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportHeight="600"
android:viewportWidth="600"> <group android:name="cpu_box">
<path
android:name="cpu"
android:fillColor="?android:textColorSecondary"
android:pathData="
M341.087,157.478 c7.417,0,13.435,6.018,13.435,13.435 v170.174c0,7.417-6.018,13.435-13.435,13.435 H170.913 c-7.417,0-13.435-6.018-13.435-13.435V170.913c0-7.417,6.018-13.435,13.435-13.435H341.087z
M390.348,157.478 c0-19.785-16.041-35.826-35.826-35.826H157.479c-19.785,0-35.826,16.041-35.826,35.826v197.043 c0,19.785,16.041,35.826,35.826,35.826h197.043c19.785,0,35.826-16.041,35.826-35.826V157.478z " />
</group>
<group android:name="bottom">
<path
android:name="wires_bottom"
android:fillColor="?android:textColorSecondary"
android:pathData="
M193.304,408.261V462h-17.913 v-53.739H193.304z
M264.957,408.261V462h-17.914v-53.739H264.957z
M300.783,408.261V462h-17.914v-53.739H300.783z
M229.13,408.261 V462h-17.913v-53.739H229.13z
M336.609,408.261V462h-17.914v-53.739H336.609z" />
</group>
<group android:name="top">
<path
android:name="wires_top"
android:fillColor="?android:textColorSecondary"
android:pathData="
M193.304,50v53.739h-17.913V50H193.304z
M264.957,50 v53.739h-17.914V50H264.957z
M300.783,50v53.739h-17.914V50H300.783z
M229.13,50v53.739h-17.913V50H229.13z
M336.609,50v53.739 h-17.914V50H336.609z " />
</group>
<group android:name="right">
<path
android:name="wires_right"
android:fillColor="?android:textColorSecondary"
android:pathData="
M408.261,318.695H462v17.914h-53.739V318.695z
M408.261,247.043H462v17.914h-53.739V247.043z
M408.261,211.217 H462v17.913h-53.739V211.217z
M408.261,282.869H462v17.914h-53.739V282.869z
M408.261,175.391H462v17.913h-53.739V175.391z" />
</group>
<group android:name="left">
<path
android:name="wires_left"
android:fillColor="?android:textColorSecondary"
android:pathData="
M50,318.695h53.739v17.914H50V318.695z
M50,247.043h53.739v17.914H50V247.043z
M50,211.217h53.739v17.913H50V211.217z
M50,282.869 h53.739v17.914H50V282.869z
M50,175.391h53.739v17.913H50V175.391z" />
</group> </vector>

res/drawable/animated_cpu.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_drawable_cpu_ani"> <target
android:name="top"
android:animation="@animator/pulse_top" /> <target
android:name="right"
android:animation="@animator/pulse_right" /> <target
android:name="left"
android:animation="@animator/pulse_left" /> <target
android:name="bottom"
android:animation="@animator/pulse_bottom" />
</animated-vector>

res/anim/anim_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="250"
android:propertyName="translateX"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="-10"
android:valueType="floatType" />
</set>

最后调用

//Support Vector Drawables
app:srcCompat="@drawable/vector_drawable_cpu_ani"
// Animated Vector Drawables
app:srcCompat="@drawable/animated_cpu"

图1 Support Vector Drawables and Animated Vector Drawables效果图

至于pathData中的东西,其实前面也有说过SVG标准指令,这里就不做过多概述了

2.AppCompat DayNight theme(DayNight 主题)

之前有看到同事折腾这个DayNight模式折腾还蛮久,不过这次谷歌出了,倒是可以省去不少时间

DayNight主题包含DayNight.NoActionBar, DayNight.DarkActionBar,
DayNight.Dialog 等等,DayNight主题支持应用切换 白天 和 夜晚 主题,根据 是否为 ‘夜晚’
决定是否从白天主题有效的切换到夜晚主题。注意这里的DayNight主题只支持API14以上

使用方法如下:

首先要设置Application或者单独Activity的theme为DayNight主题

themes.xml

<style name="AppTheme.DayNight.NoActionBar">
//other
</style>

AndroidManifest,xml

android:theme="@style/AppTheme.DayNight.NoActionBar"

DayNight主题有四个的模式:

  • MODE_NIGHT_NO 始终使用天(光)的主题

  • MODE_NIGHT_YES 始终使用夜间(黑暗)的主题

  • MODE_NIGHT_AUTO 根据一天中的时间昼/夜之间的变化。

  • MODE_NIGHT_FOLLOW_SYSTEM 此设置遵循系统的设置,基本上是以MODE_NIGHT_NO为主

我们可以通过我们通过调用AppCompatDelegate.setDefaultNightMode(),与getDelegate()。setLocalNightMode()来改变

但是两者设置是有区别的,

  • AppCompatDelegate.setDefaultNightMode()的设置是对整个App中theme为DayNight主题生效
  • getDelegate().setLocalNightMode()的设置只对于设置的地方生效

    AppCompatDelegate.setDefaultNightMode()

    public void ChangeDayNight(View v){
    switch (v.getId()){
    case R.id.day:
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
    recreate();
    break;
    case R.id.night:
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    recreate();
    break;
    }
    }

图2 AppCompatDelegate.setDefaultNightMode()设置

getDelegate().setLocalNightMode()

public void ChangeDayNight(View v){
switch (v.getId()){
case R.id.day:
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
recreate();
break;
case R.id.night:
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
recreate();
break;
}
}

图3 getDelegate().setLocalNightMode()设置

但是如果把AppCompatDelegate.setDefaultNightMode()与getDelegate().setLocalNightMode()写在一起你就会发现一个有趣的情况

public void ChangeDayNight(View v){
switch (v.getId()){
case R.id.day:
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
recreate();
break;
case R.id.night:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
recreate();
break;
}
}

图4 两种用法一起

看图可以发现,一开始都是白天模式的,然后我先设置了day及
getDelegate().setLocalNightMode()方法,然后设置了AppCompatDelegate.setDefaultNightMode()方法,但是这里的设置为night的方法并没有生效,但是当跳转到另外的一个界面的时候却发现这个界面是夜晚的模式,所以其实AppCompatDelegate.setDefaultNightMode()方法是生效了的,那么为什么在第一个界面设置AppCompatDelegate.setDefaultNightMode()方法没有生效呢?

我们看下AppCompatDelegate.setDefaultNightMode()这个方法前面的注释

Sets the default night mode. This is used across all activities/dialogs but can be overriden locally via {@link #setLocalNightMode(int)}.

所以其实当前Activity中getDelegate().setLocalNightMode()方法设置后会覆盖掉AppCompatDelegate.setDefaultNightMode()方法,导致看起来好像没有生效,其实是已经生效了的。

3.Design Support Library : Bottom Sheets (材料设计,底部表)

Design Support Library 其实准备作为Metarial Design的第四篇文章进行说明的,这里提前说明Bottom Sheets的使用

Bottom Sheets 可以在Activity,Fragment,以及Dialog中使用,使用时候继承的父类分别是:AppCompatActivity,AppCompatFragment,AppCompatDialog

先说明Bottom Sheets在Activity中的使用

1.创建Xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="bottomshets"
android:onClick="showBottom"
/> <LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="@color/colorAccent"
app:behavior_hideable="false"
app:behavior_peekHeight="0dp"
app:layout_behavior="@string/bottom_sheet_behavior"
android:orientation="horizontal"/> </android.support.design.widget.CoordinatorLayout>

布局很简单有一个Button 和一个linearLayout,其实是把这个LinearLayout作为底部弹出的View,但是注意LinearLayout多出了几个新的东西

  • app:layout_behavior="@string/bottom_sheet_behavior" 这个属性是作为Bottom Sheet必须的属性
  • app:behavior_hideable="false" 这个属性是当我们拖拽下拉的时候,bottom sheet是否能全部隐藏
  • app:behavior_peekHeight="0dp" 这个属性是当Bottom Sheets关闭的时候,底部下表我们能看到的高度

另外这里必须用CoordinatorLayout才可以生效

2.代码中

final BottomSheetBehavior behavior = BottomSheetBehavior.from(mlinearlayout);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED); mlinearlayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
});

这里是通过附加一个BottomSheetBehavior 给CoordinatorLayout的子视图,behavior.setState()是设置Bottom Sheet的状态,Bottom Sheet的状态有5种:

  • STATE_COLLAPSED: 关闭Bottom Sheets,显示peekHeight的高度,默认是0
  • STATE_DRAGGING: 用户拖拽Bottom Sheets时的状态
  • STATE_SETTLING: 当Bottom Sheets view摆放时的状态。
  • STATE_EXPANDED: 当Bottom Sheets 展开的状态
  • STATE_HIDDEN: 当Bottom Sheets 隐藏的状态

我们可以通过setBottomSheetCallback来监听Bottom Sheet的回调

behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(View bottomSheet, int newState) {
}
@Override
public void onSlide(View bottomSheet, float slideOffset) {
}
});

onSlide方法是拖拽中的回调可以根据slideOffset做动画,onStateChanged方法可以监听到状态的改变

图5 Activity中BottomSheet的使用效果图

至于Fragment的使用则与Activity中相似,就不做声明,参考Activity的使用即可。

接下来说明下Dialong的使用方式:

final BottomSheetDialog dialog = new BottomSheetDialog(this);
View view = LayoutInflater.from(this).inflate(R.layout.bottomdialog_layout, null);
LinearLayout linearLayout = (LinearLayout)view.findViewById(R.id.dialog_layout);
linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.setContentView(view);
dialog.show();

使用其实与普通的Dialog差不多

效果如下:

图6 Dialog中BottomSheet的使用效果图

如果要在Bottom Sheets里面使用滑动的布局,则需要使用NestedScrollView, RecyclerView,或者ListView/ScrollView on API 21+

4.Support v4: MediaBrowserServiceCompat

该Support
v4库用作许多支持库的基础,并且为一些新版本介绍的特征提供支持(backports)。添加到以前发布的MediaSessionCompat类,为媒体播放了提供了坚实的基础,这个版本增加了MediaBrowserServiceCompat和MediaBrowserCompat提供,带来了最新的API兼容的解决方案(甚至没有在L设备上加)支持API4+。这使得我们更容易地在Android上支持媒体的播放和在Android
Wear上浏览媒体,为我们提供了一个标准的接口,让你的媒体播放服务与界面连起来。

由于我不是很关心,所以没有了解这方法的东西,跳过

5.RecyclerView

RecyclerView组件为我们提供了灵活的创建列表和网格以及动画的特性。这个版本带来一个激动人心的新特性LayoutManager

API:自动测量!!!这允许RecyclerView尺寸大小根据其内容的大小尺寸定制。这意味着,先前不可用的情况,例如使用WRAP_CONTENT为尺寸的RecyclerView,现在都是可能的。你会发现所有内置的布局管理现在都支持自动测量。由于这种变化,一定要确保你的item的布局属性:以前被忽视的布局参数(如MATCH_PARENT的滚动方向)现在将不一样。如果你有一个自定义的LayoutManager并且不是基于之前的拓展,有一个选择就是你可以调用setAutoMeasureEnabled(true),以及做一些小的变化(详情见Javadoc)来支持新特性注意,虽然RecyclerView支持动画,但是他不支持自己动画边界变化,如果你想对RecyclerView边界进行动画处理,你可以使用
Transition APIs.

这里变化从使用代码层面来说没有什么太多变化,就不上代码了。

6.Custom Tabs(自定义选项卡)

烂尾很久了,这里看了下没有太多资料,最近又比较忙,准备下次开篇专门的文章介绍下,好的就这样了。

Android Support Library 23.2用法简析的更多相关文章

  1. Android Support Library 23.2介绍(翻译自官方文档)

    Android Support Library 23.2 (译者注:本文标注了部分文字链接,但须要***,要查看全部链接.请查看sukey=014c68f407f2d3e181b6b5e665f26a ...

  2. 手动安装Android Support Library(23.0.1)

    在搭建React-Native开发环境的时候,使用Android Sdk Manager无法找到Android Support Library这一项. 所以google了一下,找到了解决办法. 访问A ...

  3. Android support library支持包常用控件介绍(一)

    谷歌官方推出Material Design 设计理念已经有段时间了,为支持更方便的实现Material Design设计效果,官方给出了Android support design library 支 ...

  4. Android support library支持包常用控件介绍(二)

    谷歌官方推出Material Design 设计理念已经有段时间了,为支持更方便的实现 Material Design设计效果,官方给出了Android support design library ...

  5. 【Android】10.2 使用Android Support Library增强组件功能

    分类:C#.Android.VS2015: 创建日期:2016-02-18 一.简介 Android Support Library提供了一些非常漂亮的附加功能,由于这些库的引用办法都差不多,所以这一 ...

  6. 【转】Android Support Library详细介绍

    网上对Android Support Library中各个依赖包介绍的中文资料太少了,结合官方文档和有限的参考资料做了一次总结,有描述得不对的地方还请指正. 一.主工程.依赖包.jar包.androi ...

  7. Android Support Library详细介绍

    网上对Android Support Library中各个依赖包介绍的中文资料太少了,结合官方文档和有限的参考资料做了一次总结,有描述得不对的地方还请指正. 一.主工程.依赖包.jar包.androi ...

  8. Android Support Library

    title: Android Support Library tags: Support Library,支持库 grammar_cjkRuby: true --- DATE: 2016-5-13. ...

  9. Android Support Library介绍

    v4 Support Library 这个库是为Android 1.6(API版本为4)及以上的版本设计的,它包含大部分高版本中有而低版本中没有的API,包括application component ...

随机推荐

  1. JavaScript内存机制

    内存模型 JS内存空间分为栈(stack).堆(heap).池(一般也会归类为栈中). 其中栈存放变量,堆存放复杂对象,池存放常量. 基础数据类型与栈内存 JS中的基础数据类型,这些值都有固定的大小, ...

  2. 影像服务——加载CESIUM自带的影像服务

    1.加载arcgis数据——ArcGisMapServerImageryProvider var viewer = new Cesium.Viewer("cesiumDiv",{ ...

  3. list 分页

    package com.jsz.peini.common.util; import java.util.ArrayList; import java.util.List; public class S ...

  4. tf.slice()解释

    转载:https://www.jianshu.com/p/71e6ef6c121b def slice(input_, begin, size, name=None): 其中“input_”是你输入的 ...

  5. 洛谷—— P2904 [USACO08MAR]跨河River Crossing

    https://www.luogu.org/problem/show?pid=2904 题目描述 Farmer John is herding his N cows (1 <= N <= ...

  6. 我有一个idea,但是没有钱,又没技术怎么办?

    我想你还少讲一件事,就是同时如果你也没什么明确的商业计划,恭喜,那你有机会成为马云第二,因为他曾说过自己的成功要素就是「没钱」.「不懂技术」.「没有计划」,要是这么刚好让你从事互联网产业,我看不出三年 ...

  7. hadoop-12-安装ambari-agent

    hadoop-12-安装ambari-agent 在所有的机器上面安装ambari-agent 1, cd /etc/yum.repos.d/vi 三个文件vi ambari.repo#VERSION ...

  8. [Webpack + React] Import CSS Modules with TypeScript and webpack

    If you try to use CSS Modules in TypeScript the same way you would use them in JavaScript, with webp ...

  9. MongoDB count distinct group by JavaAPI查询

    import java.net.UnknownHostException; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObje ...

  10. Springmvc JSON交互

    先上前端javascript.ajax代码 <pre name="code" class="javascript"> function testAj ...