Material Design入门(下)

    除了Google官方提供的组件,Material Design另一个非常重要的特性是它的视图效果,这些效果和官方的组件一起,为安卓app的交互提供了更好的素材

1.Elevation:高度

      先介绍从Android L(5.0)以后谷歌引入的一个非常重要的概念:高度和阴影,就是将z轴引入视图的展现,让界面不再是呆板的二维视图,更真实和立体,具有视觉上的高度层次和阴影投射。

    
    这里的高度就是elevation,而实际上视图高度Z=elevation+translationZ。这里先说高度,elevation可以在布局文件或代码中指定,用dp表示,一般来说其值越大阴影越明显越柔和,但并不会改变视图本身大小。

2.轮廓和剪裁
     轮廓(Outlines)代表了图形对象的外边缘线,如果是一个以color作为背景的View,轮廓也就是该View的大小,仅仅修改elevation就可以获取阴影效果。但如果以一张图片作为背景,这时候光定义了elevation是不够的,需要通过代码指定轮廓的形状和边界。
ImageView iv = findViewById(R.id.iv);
        ViewOutlineProvider provider=new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setOval(0, 0, view.getWidth(), view.getHeight());
            }
        };
        iv.setOutlineProvider(provider);
       ViewOutlineProvider 是官方提供的一个抽象类,重写其中的方法可以轻松的改变基本的轮廓显示。同样在xml布局中,可以通过android:outlineProvider来指定轮廓的判定方式。有四种:bounds,background,none,paddedBounds,系统默认为background。
      如果想根据轮廓来缩小一个View,则可以开启剪裁功能:view.setClipToOutline(true).要注意剪裁是一个很耗资源的操作,不应该用此做动画效果。下图左边是正常的图片,右边是轮廓的长宽分别是原View的一半进行裁剪后的图片:




3.Palette:调色版
    Palette是用于谷歌提供的一个可以用于从Bitmap中提取主色调的工具类,可以让UI界面更柔和,使用起来也非常简单:首先将网络图片或者本地图片转换为Bitmap对象,然后调用Palette的异步回调,提供了六种可提取的颜色:Vibrant(有活力的)、LightVibrant(有活力的亮色)、DarkVibrant(有活力的暗色)、Muted(柔和的)、LightMuted(柔和的亮色)、DarkMuted(柔和的暗色)。下图从左至右依次展示了从示例图片中提取的六种色调。


4.Vector:矢量图

    谷歌5.0之后推出了对矢量图的支持(Vector),借鉴了Web前端强大的自定义图形的特性。好处是很明显的:可以自适配、可代替不是十分复杂的PNG图片来减小体积可将导出的标准SVG图像直接转化为PNG图像、除了静态图片还可以实现一些复杂的动画。

(1)实现静态图片:

        通过查看官方文档,其实就是一个xml文件,根元素是vector

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="300dp"
    android:height="300dp"
    android:viewportHeight="40"
    android:viewportWidth="40" >
    
    <path
        android:fillColor="#ff0040"
        android:pathData="M20.5,9.5
                        c-1.955,0,-3.83,1.268,-4.5,3
                        c-0.67,-1.732,-2.547,-3,-4.5,-3
                        C8.957,9.5,7,11.432,7,14
                        c0,3.53,3.793,6.257,9,11.5
                        c5.207,-5.242,9,-7.97,9,-11.5
                        C25,11.432,23.043,9.5,20.5,9.5z" />
</vector >
    上述代码定义的是一个桃心,几个标签的含义: android:width \ android:height:图片的宽高、 android:viewportWidth\ android:viewportHeight:图片被划分的比例大小,比如这里就是将300dp划分为40份,后面path标签中的坐标就全部使用这里划分后的坐标系统。

      重点看path中的pathData标签,用SVG语法定义了画笔该怎么画出目标图形,而不用自定义View。支持的指令如下:


    tips:坐标轴以(0,0)为中心,X轴水平向右,Y轴水平向下。所有指令大小写都可以,但是注意大写会参照全局坐标系,小写会参照父容器坐标系。指令和数据之间的空格可以省略。各种各样的SVG工具也可以帮我们导出图形,大概知道SVG语法含义即可。

5.全新的动画

   5.1 矢量动画
     上面介绍了矢量图,所以这里先介绍VectorAnim:矢量动画。谷歌提供了一个AnimatedVectorDrawable去为VectorDrawable赋予动画特性,也就是创建一个矢量资源的动画。在xml中使用的简单步骤如下:
1. 在res/drawable下创建一个根节点为<animated-vector>的xml。它相当于一个桥梁,指定要显示动画的图片和一个具体的动画。布局文件中要显示效果的控件就以它为background.
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/vector_triangle" >

    <target
        android:name="v"
        android:animation="@anim/path_morph" />

    <!--android:name="v"  指定要驱动的vetordrawable内的group和path名称 -->
    <!--android:animation="@anim/path_morph"  指定用哪个动画驱动该vectordrawable -->

</animated-vector >
2. 在res/drawable下创建 <vector>的矢量资源
<?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" >

    <path
        android:name="v"
        android:fillColor="#1a65cf"
        android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />

</vector >
3. 在res/anim下创建<objectAnimator>动画资源,也就是一个或多个对象动画器。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <objectAnimator
        android:duration="5000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
        android:valueType="pathType" >

    </objectAnimator >
</set >
4.布局文件中使用该drawable的控件,点击后开启动画
final View view = findViewById(R.id.view);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Drawable background = view.getBackground();
                if (background instanceof Animatable) {
                    ((Animatable) background).start();
                }
            }
        });
    5.2 触摸反馈
    Material Design加入了触摸反馈动画,让控件点击后交互更直观。最典型的就是水波纹动画,即控件点击后从点击位置产生类似水波纹的扩散效果。安卓5.0之后Button默认带有水波纹效果。设置水波纹背景效果有两种:

android:background="?android:attr/selectableItemBackground"     波纹有边界

android:background="?android:attr/selectableItemBackgroundBorderless"    波纹超出边界
效果图:


     5.3 揭盖动画
      不知道为什么会翻译成这个名字,大概是给人一种呈现(Reveal)的效果吧。官方提供了一个工具类ViewAnimationUtils,这个工具类非常简单,里面只有一个静态方法,返回值是一个Animator对象,为其设置时间就可以开始动画了。从名字就能看出实现的效果是以圆形展示出来的动画。
public static Animator createCircularReveal(View view,
            int centerX,  int centerY, float startRadius, float endRadius) {
        return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
    }
五个参数,view:要操作的控件;centerX、centerY:动画开始的中心点坐标,相对view自身的;startRadius:开始半径;endRadius:结束时的半径。

     5.4 过渡动画
      新增了几种Activity的过场动画。Activity的Transition有两种类型:Enter和Exit


6.RecyclerView

        RecyclerView应该算是安卓5.0中引入的最重要的控件了,和ListView一样,它也是列表容器,同样要用适配器绑定数据源。谷歌设计此控件是为了能替代ListView,它和ListView相比有以下几个特点:
(1)都要使用到适配器。ListView一般我们定义一个适配器,继承自BaseAdapter。包括里面的convertView和ViewHolder都是谷歌建议我们的一种写法,可以提供条目重用节省内存。RecyclerView同样需要适配器,继承自其内部的一个抽象类Adapter,我们只需要实现onCreateViewHolder和onBindViewHolder这两个方法就可以。
(2)RecyclerView需要设置布局管理器,否则不会显示数据。因为ListView只提供了纵向列表的展现,而RecyclerView中引入了LayoutManager(布局管理器)的概念。可以根据列表所要展现的特性自己扩展该抽象类。API提供了三种布局管理器,一般就可以满足需求
1. LinearLayoutManager 线性布局 ,效果和普通的ListView一样

2.  GridLayoutManager 网格布局
最常见的构造方法 是纵向的网格布局,第二个参数指定九宫格的列数:

        还有一种构造方法是可以指定为横向的网格布局,这时效果就类似于横向滑动的ViewPager,可以指定每页的行数。这种效果比较少见。

 3.  StaggeredGridLayoutManager  瀑布流布局
可以根据指定的方向(横,竖)系统自动切换参数为行数或者列数

(3)RecyclerView不再像ListView一样自带条目间的分隔线,需要自己实现ItemDecoration这个抽象类。第三方有很多各种各样的相关资料,现在对于竖直排列的布局,谷歌官方也提供了一个DividerItemDecoration,已经可以满足要求了,分隔线设计的过于复杂没有什么意义。
(4)列表的增删移改具有了动画效果,官方内置默认使用的动画实现是DefaultItemAnimator,另外提供了一个SimpleItemAnimator,同样你也可以自己实现RecyclerView内部的抽象类ItemAnimator来获取你要的效果。并且Adapter中提供了很多局部刷新的方法:notifyItemChanged、notifyItemInserted、notifyItemMoved、notifyItemRemoved,并且都带很自然的动画效果。不一定非使用notifyDataSetChanged来全局刷新。下例为添加和删除条目时的动画效果:

(5)不同于ListView,RecyclerView没有提供列表点击的回调事件setOnItemClickListener,可以在自定义的Adapter内部通过接口回调实现。不过我认为ViewHolder里面的成员变量itemView本身就代表了点击,我们可以将点击事件放到Adapter里面实现,不一定非要在组件上取得回调。

        以上,RecyclerView新引进了很多功能,但又最大化的提供了解耦。它自身只负责条目的回收和复用,其余的布局排列、UI实现、动画效果则全部交出去完成。
          需要注意的是:在创建Adapter时,onCreateViewHolder方法中如果用LayoutInflater加载布局,这里的父容器不能再像ListView一样置为null。否则条目中的match_parent属性等并不会真正的和父容器(RecyclerView定义的布局)参数一致,而会根据当前内容自适应宽度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值