美文网首页Android进阶+实战AndroidAndroid 精华
AndroidStudyDemo之Android5.x新API介

AndroidStudyDemo之Android5.x新API介

作者: diygreen | 来源:发表于2016-04-09 19:11 被阅读4744次
    Android5.x 思维导图

    作者:李旺成###

    时间:2016年4月9日###


    前两天稍微整理了下 Android4.x 中提供的一些新技术,当时就想着赶紧把 Android5.x 中的也整理一下。这两天整理资料的时候才发现,当时就关注了下新控件,而没有注意其他的更新。一整理,吓一跳 —— 内容很多呢(最新的思维导图里面砍了不少内容,顾不过来,挑重点的介绍下吧)。所以这里打算分成几篇文章分别介绍一下 Android 5.x 中的新 API (两篇)以及 Android 5.x 中的新控件(两到三篇)。

    这是 Android 5.x 系列的第一篇,以介绍 5.x 中提供的新 API (比较有意思的)为切入点进行展开,关于 Android 5.x 的新特性这里就不多说了,感兴趣的可以下载思维导图,里面稍微整理了点内容(作为大致了解应该够了)。

    好了,入正题,今天打算介绍几个值得注意的新 API。

    一、elevation 和 translationZ

    Android 5.0 之前 View 通过 x,y 确定其大小和位置,Android 5 引入了 Z 轴的概念,而这个 Z 轴的值就是 View 的高度(elevation),有了高度就带来了阴影。于是就出现这种风格 —— Material Design(这不是今天的重点,以后会安排专题阐述)。如下图所示:

    Android 5.0 引入了 Z 轴

    View 的 z 值包括两部分,就是标题上的 elevationtranslationZ
    eleavation:设置该组件“浮”起来的高度,通过设置该属性可以让该组件呈现3D效果
    translationZ:设置该组件在Z方向(垂直屏幕方向)上的位移,可用来做动画(回忆下属性动画中用过的 translationX 和 translationY)。

    使用方法:
    Layout:
    android:elevation
    android:translationZ
    Java 代码:
    setElevation(float)
    setTranslationZ(float)

    提示:
    新的 ViewPropertyAnimator.zViewPropertyAnimator.translationZ 方法可以设置视图的 elevation 值。(参考自:ANDROID L——Material Design详解(视图和阴影)

    看效果:

    设置不同 elevation 效果 设置不同 translationZ 效果

    上代码:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin">
    
        <!-- 通过属性设置 elevation -->
        <TextView
            android:id="@+id/tv_testeleavation1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:elevation="0dp"
            android:gravity="center"
            android:text="@string/text_0dp"
            android:textColor="#000000"
            android:textSize="20sp"
            android:textAllCaps="false"
            android:background="@drawable/bg_text"/>
        <TextView
            android:id="@+id/tv_testeleavation2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_toRightOf="@+id/tv_testeleavation1"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:elevation="15dp"
            android:gravity="center"
            android:onClick="onClick"
            android:text="@string/text_15dp"
            android:textColor="#000000"
            android:textSize="20sp"
            android:textAllCaps="false"
            android:background="@drawable/bg_text"/>
        <TextView
            android:id="@+id/tv_testeleavation3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_toRightOf="@+id/tv_testeleavation2"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:elevation="30dp"
            android:gravity="center"
            android:onClick="onClick"
            android:text="@string/text_30dp"
            android:textColor="#000000"
            android:textSize="20sp"
            android:textAllCaps="false"
            android:background="@drawable/bg_text"/>
        <TextView
            android:id="@+id/tv_testeleavation4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_toRightOf="@+id/tv_testeleavation3"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:elevation="45dp"
            android:gravity="center"
            android:onClick="onClick"
            android:text="@string/text_45dp"
            android:textColor="#000000"
            android:textSize="20sp"
            android:textAllCaps="false"
            android:background="@drawable/bg_text"/>
    
        <View
            android:id="@+id/view_test1"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:background="#00ff00"
            android:layout_centerInParent="true"
            android:clickable="true"
            android:onClick="onClick"/>
        <View
            android:id="@+id/view_test2"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_toRightOf="@+id/view_test1"
            android:layout_marginLeft="-15dp"
            android:background="#ff0000"
            android:layout_centerInParent="true"/>
        <View
            android:id="@+id/view_test3"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_margin="50dp"
            android:translationZ="20dp"
            android:background="#ff00ff"/>
    
        <!-- 通过属性设置 translationZ -->
        <View
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_toLeftOf="@+id/view_test3"
            android:layout_alignBottom="@+id/view_test3"
            android:translationZ="0dp"
            android:background="#000000"/>
    
    </RelativeLayout>
    
    

    在 Java 代码中设置,上代码:

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_testeleavation1:
                changeElevation(v);
                break;
            case R.id.tv_testeleavation2:
                changeElevation(v);
                break;
            case R.id.tv_testeleavation3:
                changeElevation(v);
                break;
            case R.id.tv_testeleavation4:
                changeElevation(v);
                break;
            case R.id.view_test1:
                changeTranslationZ(v);
                break;
        }
        mFlag = !mFlag;
    }
    
    private void changeElevation(View v) {
        v.setElevation(100.0f);
    }
    
    private void changeTranslationZ(View v) {
        if (mFlag) {
            v.setTranslationZ(120);
        } else {
            v.setTranslationZ(0);
        }
    }
    

    二、tint

    Tint:着色,对就是给背景着色,正式点的说法就是对视图进行颜色渲染。下面我们使用 tint 属性给背景调整不同颜色。

    Layout:
    android:tint
    android:backgroundTint
    android:foregroundTint
    android:drawableTint
    Java 代码:
    setImageTintList(ColorStateList tint)

    提示:
    有不少介绍 tint 属性原理的文章,感兴趣的,可以去看看。如: Andorid-Tint使用与原理解析

    先看效果图:

    tint 使用演示

    ImageView 拥有 tint 这个属性,它可以给 ImageView 的 src 设置。除了tint 之外,还有 backgroundTint, foregroundTint, drawableTint,它们分别对应对背景、前景、drawable 进行着色处理。 如上图所示,分别用src/background 与 这些属性进行了组合。

    上源码(为缩短篇幅源码做了节选,具体请下载 Demo 项目):

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin">
    
        <TextView
            android:id="@+id/tv_test1_tip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/text_test1_tip"/>
        <!-- src + tint 演示-->
        <ImageView
            android:id="@+id/iv_test1"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_below="@+id/tv_test1_tip"
            android:src="@mipmap/ic_tint_demo"/>
        <ImageView
            android:id="@+id/iv_test2"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_below="@+id/tv_test1_tip"
            android:layout_toRightOf="@+id/iv_test1"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:src="@mipmap/ic_tint_demo"
            android:tint="#2C3E50"/>
        <ImageView
            android:id="@+id/iv_test3"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_below="@+id/tv_test1_tip"
            android:layout_toRightOf="@+id/iv_test2"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:src="@mipmap/ic_tint_demo"
            android:tint="#ffcc00"/>
        
        ...
    
    </RelativeLayout>
    

    三、setClipToOutline

    View.setClipToOutline 方法可以去剪切一个视图的 outline 区域。
    要注意的是只有 rectangle, circle 和 round rectangle outlines 支持裁剪,可以调用 Outline.canClip 方法来判断是否支持裁剪。

    裁剪可以分为如下三步:

    1. 创建一个 ViewOutlineProvider
    2. 调用 setOutlineProvider 设置 ViewOutlineProvider
    3. 调用 View.setClipToOutline 方法,实现裁剪

    先看效果图:

    setClipToOutline 前后对比

    注意:
    这里面有,中兴有些机器竟然没有裁剪效果,没效果,没效果...
    上述效果为 小米 Note 更新到最新系统上实现。

    不用多解释,都在代码里,看代码:

    private void clip1() {
        ViewOutlineProvider outlineProvider = new CircleOutlineProvider();
        mViewTest1.setOutlineProvider(outlineProvider);
        mViewTest1.setClipToOutline(true);
    }
    
    private void clip2() {
        ViewOutlineProvider outlineProvider = new RoundRectOutlineProvider();
        mViewTest2.setOutlineProvider(outlineProvider);
        mViewTest2.setClipToOutline(true);
    }
    
    private void clip3() {
        ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                int margin = 20;
                int size = view.getHeight();
                outline.setRect(margin, margin, size - margin, size - margin);
            }
        };
        mViewTest3.setOutlineProvider(viewOutlineProvider);
        mViewTest3.setClipToOutline(true);
    }
    

    四、Activity Transitions 动画#

    android L 增加了一些 Activity 的转场动画 —— 爆炸、滑动、淡入淡出,让应用更加平滑。使用这些动画,需要在进入和退出 Activity 都使用这些内容转场特效,并且在 setOncontent() 方法之前。当然,也支持通过样式设置转换动画。

    Activity Transitions 有两类

    Enter(进入):进入一个 Activity 的效果
    Exit(退出):退出一个 Activity 的效果

    这每种类型又可以分为普通 Transition 和共享元素 Transition:

    普通 Transition:
    explode:从场景的中心移入或移出
    slide:从场景的边缘移入或移出
    fade:调整透明度产生渐变效果

    共享元素 Transition:
    作用是共享两个 Acitivity 中共同的元素,在 Android L 中支持如下效果:
    changeBounds - 改变目标视图的布局边界
    changeClipBounds - 裁剪目标视图边界
    changeTransform - 改变目标视图的缩放比例和旋转角度
    changeImageTransform - 改变目标图片的大小和缩放比例

    看效果:

    转场动画演示

    Activity Transition 使用简介

    通过如下两步,即可使用 Activity Transition:
    Step1: 修改 Theme,设置允许使用 transition,当然还需要设置 transition

    <style name="diygreenTheme" parent="android:Theme.Material">
        <!-- 设置允许使用 transitions -->
        <item name="android:windowContentTransitions">true</item>
    
        <!-- 指定进入和退出 transitions -->
        <item name="android:windowEnterTransition">@anim/explode</item>
        <item name="android:windowExitTransition">@anim/explode</item>
    </style>
    

    transition 动画定义:

    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">  
        <explode/>  
        <changeBounds/>  
        <changeTransform/>  
        <changeClipBounds/>  
        <changeImageTransform/>  
    </transitionSet> 
    

    当然,也可以在代码中实现上述功能(还是代码中简单灵活):

    // 允许使用 transitions  
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);  
    // 设置一个 exit transition  
    getWindow().setExitTransition(new Explode());  
    

    代码设置 transition 效果:
    Window.setEnterTransition():普通transition的进入效果
    Window.setExitTransition():普通transition的退出效果
    Window.setSharedElementEnterTransition():共享元素transition的进入效果
    Window.setSharedElementExitTransition():共享元素transition的退出效果

    Step2: 启动目标 Activity
    通过上述的 Step1,我们已经设置了允许使用 Transition,并设置了Transition 动画。现在就可以通过调用 ActivityOptions.makeSceneTransitionAnimation() 方法来启动一个新的Activity 来激活这个 Transition。

    注意: 启用共享元素 Transition普通 Transition 稍有不同。
    启用普通的 Transition:

    startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());  
    

    启用共享元素 Transition:
    要在所有需要共享视图的 Activity 中,使用 android:transitionName 属性给需要共享的元素分配一个通用的名字。如下:

    Intent intent = new Intent(this, Activity2.class);  
    // shareView: 需要共享的视图  
    // "shareName": 设置的android:transitionName="shareName"  
    ActivityOptions options = ActivityOptions  
            .makeSceneTransitionAnimation(this, shareView, "shareName");  
    startActivity(intent, options.toBundle());
    

    如有多个 View 需要共享,可通过 Pair.create() 方法创建多个匹配对,然后传入 ActivityOptions.makeSceneTransitionAnimation。代码如下:

    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,  Pair.create(shareView1, "shareName1"), Pair.create(shareView2, "shareName2"));  
    

    说明:
    如果不想使用 Transition 可以将 options bundle 置为 null。
    当需要结束当前Activity并回退这个动画时调用finishAfterTransition()方法,代码如下:

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finishAfterTransition();
    }
    

    说明:关于转场动画在这里就不多做介绍了,在 AndroidStudyDemo 系列中会专门有一个专题讲解各种动画效果。

    五、setTaskDescription

    使用android:persistableMode 属性,可以将“最近用过”屏幕中的任务设置为在重新启动过程中保持不变。
    也可以通过调用 setTaskDescription() 方法,来更改“最近用过”屏幕中活动的视觉属性,如活动的颜色、标签和图标。
    看效果:

    前后任务图对比

    代码:

    private void setDIYTaskDescription() {
        String label = "DIY-green";
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_logo);
        int colorPrimary = Color.parseColor("#666600");
        ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription(label, bitmap, colorPrimary);
        setTaskDescription(taskDescription);
        bitmap.recycle();
        bitmap = null;
    }
    

    注意:这里抛砖引玉,ActivityManager 里面与 Task 相关的还有不少好玩的,有兴趣的可以自行试试。
    说明:这里有个坑,在小米 Note 上,miui 定制了活动预览图,所以使用上述代码设置之后,无效。

    六、MediaBrowser 和 MediaSession

    android.media.browse API 能让 Android 5.0 应用在运行过程中浏览其他应用的媒体内容库。MediaBrowserService 代码能使内容显示在原应用上。总而言之,此 API 旨在实现不同应用间更好的融合——在视觉上呈现同样的用户界面,在操作上免除重复的麻烦。(引自:盘点最受开发者喜爱的Android 5.0 Lollipop API

    RemoteControlClient Deprecated

    除此之外,上图所示的 MediaSession 代替已被弃用的 RemoteControlClient,提供一组传输控制和 Media Button 的回调函数。
    下面看一下这两个类所在包,和类图:

    MediaBrowse Package MediaBrowse Class MediaSession Package MediaSession Class

    本来想提供一些示例代码,在网上查找资料的时候发现一个使用了这两个类的项目,代码量不是很小,所以做了一半就不打算继续写了。感兴趣的童鞋,可以参考一下这个项目:MediaBrowserService 音乐播放项目

    七、Camera2 API

    从5.0开始(API Level 21),可以完全控制安卓设备相机的新api Camera2 (android.hardware.Camera2)被引入了进来。在以前的 Camera api(android.hardware.Camera)中,对相机的手动控制需要更改系统才能实现,而且 api 也不友好。这些老的 Camera API 在 5.0 上已经过时,在以后的 app 开发中推荐的是 Camera2 API。

    有哪些改进:

    • 支持30fps的全高清连拍
    • 支持帧之间的手动设置
    • 支持RAW格式的图片拍摄
    • 支持快门0延迟以及电影速拍
    • 支持相机其他方面的手动控制包括噪音消除的级别
    Camera2 包下的类

    相机的基本使用被分成了5个主要部分

    1. CameraManager
      提供构建,列出以及链接相机设备的接口
    2. CameraDevice
      代表和安卓设备相连的单个相机
    3. CameraCaptureSession
      提供一套输出目标的
    4. CaptureRequest
      请求从相机获取照片
    5. CaptureResult
      从图像传感器获得的单个图片拍摄的结果

    Camera 2 API 使用步骤:(参考自:Android 5.0 Lollipop新的摄像头API

    1. 获取 CameraManager 实例,然后就可以遍历、查询和打开一个 Camera 对象
    2. 通过 CameraManager 对象的 getCameraCharacteristics() 方法来获得 CameraCharacteristics 对象,该对象包含设备的设置信息和输出参数
    3. 调用 camera.createCaptureSession() 可获得 CameraCaptureSession 对象,该对象为每个预览对象进行预设置,如大小和格式(当然这些格式得是设备所支持的)
    4. 创建 SurfaceView 或 TextureView 渲染图像
    5. 构造一个 CaptureRequest 对象,来描述每次捕获图片的具体设置
    6. 调用 capture() 方法完成图像的捕获

    相机没有过多研究,这里就不贴代码了,推荐几个使用 Camera API 2 开发的开源项目:

    1. Camera2 Basic
      演示如何使用 Camera2 API 基本功能的 demo。你可以从中学会如何遍历相机设备的所有特性,显示预览照片,以及拍照。
    2. Camera2 Video
      这个 demo 演示如何使用 Camera2 API 录制视频。
    3. Camera2 master
      使用Android L Camera2 API开发的示例应用程序,具备拍照,AWB,Flash,连拍功能
    4. LCamera
      L Camera 是一个开源的实验性质的 Camera 应用程序,基于 Android L 提供的新 API android.hardware.camera2,目前只支持在 Andorid 5.0 Lollipop 版本的 Nexus 5 和 Nexus 6上运行

    今天的进度比我的预期慢了很多,主要是因为相机这一块很不熟悉,今天先到这里,明天有时间继续,希望会做得更好...

    示例代码:GitHub

    Android 5.x 介绍第二篇来了!
    AndroidStudyDemo之Android5.x新API介绍(二)

    附录

    Android 5.x 思维导图
    Android 5.x 思维导图.png

    参考

    盘点最受开发者喜爱的Android 5.0 Lollipop API
    Android 5.0新增5000多个API
    Android 5.0 API新增和改进
    ANDROID L——Material Design详解(视图和阴影)
    Android Tint使用
    Andorid-Tint使用与原理解析
    ANDROID L——Material Design详解(动画篇)
    浅析Android 5.0中多媒体相关的新特性
    Android -- Camera2(Android5.0)
    使用Camera2 替代过时的Camera API
    Android实战技巧之三十三:android.hardware.camera2使用指南

    相关文章

      网友评论

      本文标题:AndroidStudyDemo之Android5.x新API介

      本文链接:https://www.haomeiwen.com/subject/wpbvlttx.html