博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 5.0 新特性
阅读量:5254 次
发布时间:2019-06-14

本文共 10355 字,大约阅读时间需要 34 分钟。

Material Design

 
 

Material Design简介

Material Design是谷歌新的设计语言,谷歌希望寄由此来统一各种平台上的用户体验,Material Design的特点是干净的排版和简单的布局,以此来突出内容

Material Design对排版、材质、配色、光效、间距、文字大小、交互方式、动画轨迹都做出了建议,以帮助设计者设计出符合Material Design风格的应用。

Material Design设计语言鼓励大家使用充满活力的鲜艳色彩,并在同一界面建议使用三种色调,并保障有一个强色调,强色一般处于处于视图最底层,例如状态栏或者actionbar。通过强色调形成鲜明的对比,更容易突出内容的重要性。对于文字色彩的取值,Material Design建议在浅色背景上采用黑色,在深色背景上采用白色。重要信息和标题采用87%透明度,次要文字采用54%透明度,而更次要的说明文字可以采用26%的透明度。对于想特别突出或者可点击的文字,建议使用强色调。不同层级的视图,可以通过阴影来凸显。对于带有操作且内容突出的区域,可以使用cardview进行隔离,对于内容不太重要或者操作比较单一的区域,可以使用分割线进行隔离。

更多详情请见Material Design文档:

中文版网站 

英文版 

Material Design使用

作为我们开发者,最关心的还是如何在项目中使用Material Design风格:

  1. 设置应用的 targetSdkVersion 为21
  2. 在values目录下的style资源文件中创建一个style,让其继承自 android:Theme.Material
  3. 在AndroidManifest中指定应用的主题或者Activity的主题为我们设定的样式

谷歌官方我们提供了三种配色风格的Material Design样式:

  1. 黑色主题 Theme.Material
  2. 明亮主题 Theme.Material.Light
  3. 明亮主题黑色ActionBar Theme.Material.Light.DarkActionBar

我们也可以继承系统提供的Material Design样式,进行配色修改:

Mou icon

  1. android:colorPrimaryDark 应用的主要暗色调,statusBarColor默认使用该颜色
  2. android:statusBarColor 状态栏颜色,默认使用colorPrimaryDark
  3. android:colorPrimary 应用的主要色调,actionBar默认使用该颜色
  4. android:windowBackground 窗口背景颜色
  5. android:navigationBarColor 底部栏颜色
  6. android:colorForeground 应用的前景色,ListView的分割线,switch滑动区默认使用该颜色
  7. android:colorBackground 应用的背景色,popMenu的背景默认使用该颜色
  8. android:colorAccent 一般控件的选中效果默认采用该颜色
  9. android:colorControlNormal 控件的默认色调 
  10. android:colorControlHighlight 控件按压时的色调
  11. android:colorControlActivated 控件选中时的颜色,默认使用colorAccent
  12. android:colorButtonNormal 默认按钮的背景颜色
  13. android:textColor Button,textView的文字颜色
  14. android:textColorPrimaryDisableOnly RadioButton checkbox等控件的文字
  15. android:textColorPrimary 应用的主要文字颜色,actionBar的标题文字默认使用该颜色

主题不仅可以对ApplicationActivity使用,也可以对某一个控件单使用,或者是在xml布局中给一个根节点控件设置android:theme属性,来修改它和它所有子控件的主题。 如果我们要对特定控件实例做自定义修改,建议通过控件自身的API进行设置修改。

Material Design兼容性

Material Design主题只有在API级别为21以上才可使用,在v7支持库中提供了部分控件的Material Design主题样式,如果想使应用在android的所有版本上都能统一风格,我们可以对控件效果做自定义或者使用一些第三方的兼容包。目前最有效的做法是针对21版本创建value-21资源目录,使用Material Design风格主题,在其他版本使用v7的Theme.AppCompat.Light风格主题。

阴影和裁剪

 
 

View的z属性

Material Design建议为了凸显布局的层次,建议使用阴影效果,并且Android L为了简化大家的工作,对View进行了扩展,能使大家非常方便的创建阴影效果:

阴影

给View添加了一个新的属性:Z 属性,用于描述视图距离它父视图的高度:

在5.0之前,我们的视图都是二维的,只有x轴和y轴,现在,android新增了z轴。x轴和y轴描述了一个view的大小和位置,而z轴描述了view在父视图上抬起的视觉,体现效果就是阴影。下图的两个view的z属性分别为2dp和8dp的视觉效果:

z轴

View的Z属性可以通过elevation和translationZ进行修改。

z = elevation+translationZ

在5.0之前,我们如果想给view添加阴影效果,以体现其层次感,通常的做法是给view设置一个带阴影的背景图片,现在,我们只需要简单的修改view的Z属性,就能让其具备阴影的层次感。

Z属性会扩大view的显示区域,如果它的大小大于或等于父视图的大小,那么它的阴影效果就无法显示了,view并不会因为z属性而把自身缩小腾出空间显示阴影

Z属性不仅影响着view的阴影效果,还影响着view的绘制顺序,在同一个父view内部,Z属性越小,绘制的时机就越早。也就是优先被绘制,而z属性越大,则绘制时间越晚,后绘制的将会遮盖住先绘制的,只有Z属性相同,才按照添加的顺序绘制。

View的轮廓

在Android的世界里,所有的View都是矩形的,虽然可以给View设置背景圆形的图片,即可在界面显示出圆形的内容,但是View的大小实际上仍然是矩形,并且设置的图片也是实际上也是矩形,只是圆形意外的区域为透明色。

如果系统根据View的大小来为我们生成对应的阴影,有时候就会出现很奇怪的效果。

为了解决该类问题,View增加了一个新的描述来指明内容显示的形状,这就是轮廓。通过shape设置的背景,View会自动根据shape的形状进行轮廓判定,通过color设置的背景,View默认其轮廓和View的大小一样。但是通过图片进行背景设置,View则无法获知轮廓的形状,这个时候就需要我们程序员显示的指定。

在xml布局中,可以通过android:outlineProvider来指定轮廓的判定方式:

  1. none 即使设置了Z属性,也不会显示阴影
  2. background 会按照背景来设置阴影形状
  3. bounds 会按照View的大小来描绘阴影
  4. paddedBounds 和bounds类似,不过阴影会稍微向右偏移一点

在代码中,我们可以通过setOutlineProvider来指定一个View的轮廓:

ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {    public void getOutline(View view, Outline outline) {        // 可以指定圆形,矩形,圆角矩形,path        outline.setOval(0, 0, view.getWidth(), view.getHeight());    }};View.setOutlineProvider(viewOutlineProvider );

注意:如果采用图片作为背景,即使在xml布局中指定android:outlineProvider为background也不会显示阴影,只有通过代码中指定轮廓来显示。

View的剪裁

给View指定轮廓,可以决定阴影的显示形状,如果给View指定一个小于自身大小的轮廓,正常情况下阴影会被View遮住,这个时候View的显示内容并没有因为轮廓的缩小而缩小。

如果想根据轮廓来缩小一个View,则可以通过剪裁。如果一个View指定了轮廓,调用setClipToOutline方法,就可以根据轮廓来剪裁一个View。想要剪裁轮廓,必须要给View先指定轮廓,并且轮廓是可以被剪裁的,目前只有圆形,矩形,圆角矩形支持剪裁,可以通过outline.canClip()来判断一个轮廓是否支持剪裁。

Path剪裁不会改变View的大小,但是如果Path的范围比View要的bounds要小,则剪裁后会改变View的位置,位置偏移和Z属性有关,这可能是一个BUG,view的设计者可能在绘制阴影时根据轮廓偏移了画布,而在绘制完后忘记把画布还原了。

剪裁不会改变View的测量大小和布局大小,也不会改变View的触摸区域,剪裁只是在onDraw的时候对画布做了剪裁处理,剪裁也不同于scale,scale是调整画布matrix的缩放属性,调整后,View仍然能完整显示,而剪裁是缩小画布的剪裁区域,剪裁后我们只能看到View的一部分。

试图给View一个比较大的轮廓进行剪裁也是不成功的,实验证明剪裁后的View只能比原有体积小,扩大轮廓只会扩大轮廓的绘制区域

剪裁是一个非常消耗资源的操作,我们不应该用此来做动画效果,如果要实现这样的动画,可以使用Reveal Effect

图片和颜色

 
 

tint属性

tint属性是一个颜色值,可以对图片做颜色渲染,我们可以给view的背景设置tint色值,给ImageView的图片设置tint色值,也可以给任意Drawable或者NinePatchDrawable设置tint色值。

在应用的主题中也可以通过设置 android:tint 来给主题设置统一的颜色渲染。

tint的渲染模式有总共有16种,xml文件中可以使用6种,代码中我们可以设置16种,渲染模式决定了渲染颜色和原图颜色的取舍和合成规则:

  1. PorterDuff.Mode.CLEAR 所绘制不会提交到画布上。
  2. PorterDuff.Mode.SRC 显示上层绘制图片
  3. PorterDuff.Mode.DST 显示下层绘制图片
  4. PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖。
  5. PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示。
  6. PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层。
  7. PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层。
  8. PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。
  9. PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。
  10. PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分
  11. PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分
  12. PorterDuff.Mode.XOR 取两层绘制非交集。两层绘制非交集。
  13. PorterDuff.Mode.DARKEN 上下层都显示。变暗
  14. PorterDuff.Mode.LIGHTEN 上下层都显示。变亮
  15. PorterDuff.Mode.MULTIPLY 取两层绘制交集
  16. PorterDuff.Mode.SCREEN 上下层都显示。

通过tint属性处理后的图片会和原图显示出不一样的颜色,我们可以通过这种方式利用一张图片做出图片选择器的效果,让控件在按压状态下显示另外一种颜色:

通过给图片设置tint色生成另外一种图片 
利用新的图片生成图片选择器

Palette调色版

Palette调色板,可以很方便的让我们从图片中提取颜色。并且可以指定提取某种类型的颜色。

  1. Vibrant 鲜艳的
  2. Vibrant dark鲜艳的暗色
  3. Vibrant light鲜艳的亮色
  4. Muted 柔和的
  5. Muted dark柔和的暗色
  6. Muted light柔和的亮色

对图片取色是一个比较消耗性能的操作,其内部会对图片的像素值进来遍历以分析对比,所以我们要在异步线程中去完成。

如果操作本来就属于后台线程,可以使用:Palette p = Palette.generate(Bitmap bitmap);如果在主线程中,我们可以使用异步的方式:Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {        public void onGenerated(Palette palette) {  }});

当操作完成后或者异步回调后,我们就可以使用以下方式来获取对应的色值了,并且可以在没有获取到的情况下之指定默认值:

p.getVibrantColor(int defaultColor);p.getDarkVibrantColor(int defaultColor);p.getLightVibrantColor(int defaultColor);p.getMutedColor(int defaultColor);p.getDarkMutedColor(int defaultColor);p.getLightMutedColor(int defaultColor);

在使用palette之前,bitmap提供获取指定位置的像素值:

bitmap.getPixel(x,y)

但是该方式只能获取某一点的像素值,palette是对整个bitmap的所有像素值进行分析,并选出几个像素占比比较多的像素值,这样选择出来的色值更符合图片的整体色值。

vector矢量图

矢量图也称为面向对象的图像或绘图图像,是计算机图形学中用点、直线或者多边形等基于数学方程的几何图元表示的图像。矢量图形最大的优点是无论放大、缩小或旋转等不会失真;最大的缺点是难以表现色彩层次丰富、逼真的图像效果。

Android L开始支持矢量图,我们可以用它来处理一些图形简单的icon,方便我们的适配。

Android L中对矢量图的支持是通过xml文件构建,通过矢量图的path描述来生成一个矢量图,对应的java对象为VectorDrawable。

下面是官方文档提供的一个矢量图,利用改文件,我们可以创建一个随意放大缩小都不会失真的心形。

矢量图的pathData数据就是用来描述矢量图的数学公式,其含义如下表:

命令类型 使用描述 代表含义 举例说明
移动指令 M x,y M移动绝对位置 M 100,240
移动指令 m x,y m移动相对于上一个点 m 100,240
绘制 L 或 l 从当前点绘制直线到指定点 L 100,100
绘制 H 或 h 水平直线 h 100
绘制 V 或 v 垂直直线 v 100
绘制 C 或 c 三次方程式贝塞尔曲线 C 100,200 200,400 300,200
绘制 Q 或 q 二次方程式贝塞尔曲线 Q 100,200 300,200
绘制 S 或 s 平滑三次方程式贝塞尔曲线 S 100,200 200,400 300,200
绘制 T 或 t 平滑二次方程式贝塞尔曲线 T 100,200 300,200
绘制 A 或 a 椭圆 A 5,5 0 0 1 10,10
关闭指令 Z 或 z 将图形的首、尾点用直线连接 Z
填充 F0 EvenOdd 填充规则
填充 F1 Nonzero 填充规则

通过path命令来进行简单的图形还是可行的,但是复杂的图形我们就需要借助工具来生成了,比如使用 Expression Design,就可以直接粘贴来自其它软件的矢量图形,然后选择导出,导出时做如后选择:文件->导出->导出属性->格式->XAML Silverlight 画布,即可得到XAML格式的矢量图形,也就是Path。

更多矢量图学习可参考: 我们可以访问 在线制作矢量图并导出path。

新增Widget

 
 

RecyclerView

RecyclerView是ListView的升级版,它具备了更好的性能,且更容易使用。和ListView一样,RecyclerView是用来显示大量数据的容器,并通过复用有限数量的View,来提高滚动时的性能。当你的视图上的元素经常动态的且有规律的改变时候,可以使用RecyclerView控件。

与ListView不同的是RecyclerView不再负责布局,只专注于复用机制,布局交由LayoutManager来管理。 RecyclerView仍然通过Adapter来获取需要显示的对象。

Mou icon

要使用RecyclerView组件,创建Adapter不再继承自BaseAdapter,而是应该继承自RecyclerView.Adapter类,并且最好指定一个继承自RecyclerView.ViewHolder的范型,Adapter不再要求你返回一个View,而是一个ViewHolder。

继承自Adapter后,需要实现3个抽象方法:

 

新的Adapter和原有的Adapter并没有太多的差别,只是不再需要我们写复用判断的逻辑,因为复用逻辑其实都是相似的,它已经有了自身的实现。和原有的Adapter一样,仍然可以通过notifyDataSetChanged来刷新UI,通过getItemViewType来获取对应位置的类型,但是它不再需要你指定有多少类型了,因为该方法已经能够判断出有多少类型。新增的onViewRecycled方法可以让使用者监听View被移除屏幕的时机,并且还提供了一个AdapterDataObserver的观察者,对外提供数据改变时的回调。

ViewHolder是对所有的单个item的封装,不仅包含了item需要显示的View,并且还包含和item相关的其它数据,例如:当前的position、之前的position、即将显示的position、被回收的次数、View的类型、是否处于显示中等信息。创建一个ViewHolder需要传递一个View对象,这个View就是该holder的显示视图,该View中通常会包含一些子视图,我们最好把这些子视图都记录在holder中,便于复用时设置不同的数据。

RecyclerView不再对布局进行管理,而是通过LayoutManager管理布局,我们可以通过继承自LayoutManager来实现特殊的布局,系统提供了三种常用的布局管理器:

  1. LinearLayoutManager 线性布局
  2. GridLayoutManager 九宫格布局
  3. StaggeredGridLayoutManager 瀑布流布局

并且每一种都可以设置横行和纵向的布局,可惜的均不能添加header,如果要添加header,我们可以在Adapter中使用不同的类型来达到该效果。

RecyclerView默认提供了item的增加和删除的动画效果,如果我们使用自定义的动画,需要继承继承RecyclerView.ItemAnimator类,通过RecyclerView.setItemAnimator()方法来设置我们自定义的动画。

CardView

在实现扁平化的UI处理上,通常离不开阴影和圆角,我们通常是让美工提供一个带有阴影和圆角效果的背景图片,现在我们有了更好的实现方式,那就是CardView。

CardView实际是一个FrameLayout类的子类,它为视图提供卡片样式,并保持在不同平台上拥有统一的风格。CardView组件可以设定阴影和圆角。

我们可以使用cardElevation属性在xml布局中设置阴影效果,在代码中可以通过setCardElevation达到同样的效果。阴影的设置和Android L中的Z属性类似。

设置圆角也相当容易,在xml中通过cardCornerRadius来设置,在代码中则使用setRadius,圆角的设置和Android L中的剪裁很相似。

如果我们想设置cardview的背景,请注意使用carBackgroundColor方法,setBackgroundColor也许会影响我们的圆角效果

ToolBar

Toolbar是android L引入的一个新控件,用于取代ActionBar,它提供了ActionBar类似的功能,但是更灵活。不像ActionBar那么固定,Toolbar更像是一般的View元素,可以被放置在view树体系的任意位置,可以应用动画,可以跟着ScrollView滚动,可以与布局中的其他View交互。当然,你还可以用Toolbar替换掉ActionBar,只需调用Activity.setActionBar()。

为了兼容更多的设备一般我们都是通过AppCompat中的android.support.v7.widget.Toolbar来使用Toolbar。

有两种使用Toolbar的方式:

  1. 将Toolbar当作actionbar来使用。这种情况一般发生在你想利用actionbar现有的一些功能(比如能够显示菜单中的操作项,响应菜单点击事件,使用ActionBarDrawerToggle等),但是又想获得比actionbar更多的控制权限。
  2. 将Toolbar当作一个独立的控件来使用,这种方式又名Standalone。

如果你要将Toolbar当作actionbar来使用,你首先要去掉actionbar,最简单的方法是使用Theme.AppCompat.NoActionBar主题。或者是设置主题的属性android:windowNoTitle为true。然后在Activity的onCreate中调用setSupportActionBar(toolbar),原本应该出现在ActionBar上的menu会自动出现在actionbar上。

Toolbar的高度、宽度、背景颜色等等一切View的属性完全取决于你,这都是因为Toolbar本质上只是个ViewGroup。将Toolbar当作一个独立的控件来使用是不需要去掉actionbar的(两者可以共存),可以使用任意主题。但是在这种情况下,menu菜单并不会自动的显示在Toolbar上,Toolbar也不会响应菜单的回调函数,如果你想让menu菜单项显示在Toolbar上,必须手动inflate menu。

 

兼容性

 
 

虽然Material Design新增了许多新特性,但是并不是所有新内容对对下保持了兼容。

使用v7包

v7 support libraries r21 及更高版本包含了以下Material Design特性:

  1. 使用Theme.AppCompat主题包含调色板主体属性,可以对应用的主题做统一的配色,但是不包括状态栏和底部操作栏
  2. RecyclerView和CardView被独立出来,只要引入jar包,即可适配7以上的所有版本。
  3. Palette类用于从图片提取主色调

系统组件

Theme.AppCompat主题中提供了这些组件的Material Design style:

  1. EditText
  2. Spinner
  3. CheckBox
  4. RadioButton
  5. SwitchCompat
  6. CheckedTextView
  7. Color Palette

创建多个value和layout

针对Android L我们可以创建value-v21指定Material Design主题,而在其他value中指定Theme.AppCompat。layout布局也可以采用该方式,在Android L中使用系统控件,在低版本中使用我们自定义的控件活着第三方包来达到该效果。

注意版本检查

以下特性只在Android 5.0 (API level 21) 及以上版本中可用:

  1. 转场动画
  2. 触摸反馈
  3. 圆形展示动画
  4. 路径动画
  5. 矢量图
  6. tint染色

所以在代码中遇上使用这些api的地方需要进行版本判断:

 

第三方支持库

RippleDrawable

提供触摸反馈特效,即5.0的button按压下的水波纹效果。

  1.  
  2.  
  3.  
状态动画

 

Material Design风格的对话框

 

Material Design风格兼容包

提供了不少控件特效 

SystemBarTint

支持修改状态栏和底部操作栏  

转载于:https://www.cnblogs.com/baiqiantao/p/6243118.html

你可能感兴趣的文章
面向对象——对象的使用
查看>>
javascript parseUrl函数(来自国外的获取网址url参数)
查看>>
C#基础精华08(反射,程序集)
查看>>
javascript基础:window对象内置对话框、模式和非模式对话框、传值方法
查看>>
springboot学习(一):创建项目
查看>>
选择器
查看>>
Google最新截屏案例详解
查看>>
文件对比与差异提取的实现
查看>>
修长城 (区间DP)
查看>>
android intent 传递list或者对象
查看>>
javascript面向对象精要第二章函数整理精要
查看>>
iOS开发——Xcode快捷键
查看>>
linux虚拟机CentOS 7完整安装流程截图
查看>>
AndroidManifest.xml文件详解(uses-feature)
查看>>
bzoj 1087 互不侵犯King
查看>>
(随笔)关于人生的一点新感悟
查看>>
JavaScript 随意记
查看>>
CodeForces 1103E. Radix sum
查看>>
Virtual PC2007 + Redhat9下的网络配置
查看>>
字体的术语
查看>>