详解Android Material Design自定义动画的编写

新的动画Api,让你在UI控件里能创建触摸反馈,改变View的状态,切换activity的一系列自定义动画
具体有:

  • 响应View的touch事件的触摸反馈动画
  • 隐藏和显示View的循环展示动画
  • 两个Activity间的切换动画
  • 更自然的曲线运动的动画
  • 使用View的状态更改动画,能改变一个或多个View的属性
  • 在View的状态更改时显示状态列表动画

这些new animations Api,已内置在标准Widget中,如Button。在自定义view时也可使用这些api

动画在Material设计中,为用户与app交互反馈他们的动作行为和提供了视觉上的连贯性。Material主题为Buttons和Activity的过渡提供了一些默认的动画,在android5.0(api21)及以上,允许自定义这些动画:

  • Touch feedback  触摸反馈
  • Circular Reveal  循环显示
  • Activity transitions  活动过渡
  • Curved motion       曲线运动
  • View state changes  视图状态变化
  • Customize Touch Feedback  自定义触摸反馈动画

在Material设计中,触摸反馈提供了一种在用户与UI进行交互时 即时可视化的确认接触点。关于buttons默认的触摸反馈动画,使用了RippleDrawable类,用一个波纹(涟漪)效果在两种不同的状态间过渡。

在多数情况下,你需要在view的xml定义中,定义它的背景:

  • android:attr/selectableItemBackground                              有界限的波纹
  • android:attr/selectableItemBackgroundBorderless             延伸到view之外的波纹     note:该属性为api21添加

或者,你可以用xml定义一个RippleDrawable类型的资源,并使用波纹属性。

你可以指定一个颜色给RippleDrawable对象,以改变它的默认触摸反馈颜色,使用主题的android:colorControlHighlight属性。
Use the Reveal Effect  使用展现效果
ViewAnimationUtils.createCircularReveal()方法使您能够激活一个循环显示或隐藏一个视图。
显示:

// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the final radius for the clipping circle
int finalRadius = myView.getWidth();

// create and start the animator for this view
// (the start radius is zero)
Animator anim =
  ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
anim.start();
隐藏
// previously visible view
final View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the initial radius for the clipping circle
int initialRadius = myView.getWidth();

// create the animation (the final radius is zero)
Animator anim =
  ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
  @Override
  public void onAnimationEnd(Animator animation) {
    super.onAnimationEnd(animation);
    myView.setVisibility(View.INVISIBLE);
  }
});

// start the animation
anim.start();

Customize Activity Transitions  定义Activity的过渡动画

  • 一个enter transition表示,Activity的进入场景。比如一个explode enter transition,表示Views的进入场景:飞快的从外部向屏幕中心移动。
  • 一个exit transition表示,Activity的离开场景。比如一个explode exit transition,表示Views的离开场景:从屏幕中心散开。
  • 一个share transition表示,在两个Activity间共享它们的activity transtion。比如,两个Activity有一个相同的图片,而位置和尺寸不同,使用changeImageTransform这个共享元素,能在Activity间平稳的转换和缩放图片。

android5.0(api21)及以上,支持这些效果的transition(过渡):

  • 爆炸——移动视图或从场景中心。class Explode
  • 滑行——移动视图或从一个场景的边缘。class Slide
  • 淡入淡出——添加或从场景中删除视图通过改变其透明度。 class Fade

也支持这些共享元素(都有对应的class)转换:

  •   changeBounds ——View的布局的边界变化。
  •   changeClipBounds——View的裁剪边界变化。
  •   changeTransform——View的旋转、缩放边界变化
  •   changeImageTransform——目标图像的尺寸和缩放变化。

  当启用活动在你的应用程序转换,默认同时淡出淡入之间的过渡是激活进入和退出活动。

Specify custom transitions 自定义过渡动画
首先需要在定义主题的style中,使用android:windowContentTransitions属性,声明使用transitions。也可以定义使用的Transitions:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyTheme" parent="@android:style/Theme.Material">
    <!-- enable window content transitions -->
    <item name="android:windowContentTransitions">true</item>
    <!-- specify enter and exit transitions -->
    <item name="android:windowEnterTransition">@android:transition/explode</item>
    <item name="android:windowExitTransition">@android:transition/explode</item>
    <!-- specify shared element transitions -->
    <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
    <item name="android:windowSharedElementExitTransition">@android:transition/slide_top</item>
  </style>
</resources>

注:每个transition的xml中定义的就是一组change的元素
在代码中启用transitions:

// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// set an exit transition
getWindow().setExitTransition(new Explode());
在代码中设置transitions的方法还有
Window.setEnterTransition()
Window.setExitTransition()
Window.setSharedElementEnterTransition()
Window.setSharedElementExitTransition()

要想尽快进行transitions过渡,可在Activity中调用Window.setAllowEnterTransitionOverlap()。
Start an activity using transitions 使用过渡启动Activity
如果你要启用transtions并设置为一个Activity的结束exit transtion,当你以如下方式启动另一个Activity时,它将被激活:

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

当你在另一个Activity中设置了enter transtion,在其启动时,它将被激活。想要disable transitions,那么在启动另一个Activity时:

startActivity(intent,null); //传递null 的options bundle

Start an activity with a shared element  使用一个共享元素启动Acitvity

1.在主题中启用window content
2.在style中定义共享的过渡transitions
3.定义transitions的xml资源  res/transition
4.在layout中调用android:transitionName="" 设置第3步中定义的名字
5.调用 ActivityOptions.makeSceneTransitionAnimation()生成相应的ActivityOptions对象。

// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    Intent intent = new Intent(this, Activity2.class);
    // create the transition animation - the images in the layouts
    // of both activities are defined with android:transitionName="robot"
    ActivityOptions options = ActivityOptions
      .makeSceneTransitionAnimation(this, androidRobotView, "robot");
    // start the new activity
    startActivity(intent, options.toBundle());
  }
});

在代码中可以用View.setTransitionName()来设置过渡动画
当你要关闭第二个Activity时,要反转过渡动画,那么可以调用Activity.finishAfterTransition()方法,而不是Activity.finish()。
Start an activity with multiple shared elements  用多共享元素启动Activity
若两个Activity拥有不只一个的共享元素,要在它们之间开始场景transition动画,在它们的layout中都要使用 android:transitionName (或在Activity中代码中调用View.setTransitionName() )来定义,并创建一个如下的 ActivityOptions 对象:

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
    Pair.create(view1, "agreedName1"),
    Pair.create(view2, "agreedName2"));

Use Curved Motion 使用曲线运动
在Material设计中的动画,依赖于曲线的时间插入值和空间运动模式。在android5.0(api21)及以上,可以自定义动画时间曲线和曲线运动模式。

PathInterpolator类是一个新的基于贝塞尔曲线或路径对象的插入器。这个插入器指定了一个1 x1正方形运动曲线,它使用(0,0)为锚点,(1,1)为控制点,作为构造函数的参数。你也可以定义一个path interpolator的xml资源:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
  android:controlX1="0.4"
  android:controlY1="0"
  android:controlX2="1"
  android:controlY2="1"/>

系统提供了三种基本的曲线,XML资源:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

您可以用PathInterpolator对象作Animator.setInterpolator()方法的参数。

ObjectAnimator类有新构造函数使您能够激活坐标沿着一个path同时使用两种或两种以上的属性。比如,如下的animator就使用了一个path 对象,来同时操作View的x和y属性:

ObjectAnimator mAnimator;
mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
...
mAnimator.start();

Animate View State Changes  视图状态改变动画

StateListAnimator类允许您定义动画运行时视图的状态变化。下面的例子演示如何在xml中定义一个StateListAnimator:

<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_pressed="true">
  <set>
   <objectAnimator android:propertyName="translationZ"
    android:duration="@android:integer/config_shortAnimTime"
    android:valueTo="2dp"
    android:valueType="floatType"/>
    <!-- you could have other objectAnimator elements
       here for "x" and "y", or other properties -->
  </set>
 </item>
 <item android:state_enabled="true"
  android:state_pressed="false"
  android:state_focused="true">
  <set>
   <objectAnimator android:propertyName="translationZ"
    android:duration="100"
    android:valueTo="0"
    android:valueType="floatType"/>
  </set>
 </item>
</selector>

在上例中,为一个View添加视图状态动画,定义了一个使用selector元素的xml资源,并赋给view的android:stateListAnimator属性。如要在代码中为View指定视图状态动画,可使用AnimationInflater.loadStateListAnimator()加载xml资源,并使用View.setStateListAnimator()将其指定给View。
当你的主题继承了Material主题,按钮默认拥有了z动画。为了避免这种行为在你的按钮,设置android:stateListAnimator属性值为null。
AnimatedStateListDrawable类允许您创建图片以显示关联View的状态改变动画。一些系统的Widget,在5.0上默认使用这些动画。下面的例子显示了如何定义一个AnimatedStateListDrawable作为XML资源:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
  xmlns:android="http://schemas.android.com/apk/res/android">

  <!-- provide a different drawable for each state-->
  <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
    android:state_pressed="true"/>
  <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
    android:state_focused="true"/>
  <item android:id="@id/default"
    android:drawable="@drawable/drawableD"/>

  <!-- specify a transition -->
  <transition android:fromId="@+id/default" android:toId="@+id/pressed">
    <animation-list>
      <item android:duration="15" android:drawable="@drawable/dt1"/>
      <item android:duration="15" android:drawable="@drawable/dt2"/>
      ...
    </animation-list>
  </transition>
  ...
</animated-selector>

Animate Vector Drawables  矢量图片动画
矢量图片是可伸缩而不失真的。AnimatedVectorDrawable类让你能使一个矢量图动起来。
通常在三种xml定义动态的矢量图:

  • 使用<vector>元素的矢量图,在res/drawable/
  • 一个动态矢量图,使用<animated-vector>元素,在res/drawable/
  • 一个或多个object animator,使用<objectAnimator>元素,在res/animator/

矢量图可以定义的属性元素有<group>和<path>,<group>定义了一个<path>的集合,或者子<group>,<path>定义绘制的路径。

定义矢量图时,可以给<group>和<path>指定一个名字,示例如下:

<!-- res/drawable/vectordrawable.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:height="64dp"
  android:width="64dp"
  android:viewportHeight="600"
  android:viewportWidth="600">
  <group
    android:name="rotationGroup"
    android:pivotX="300.0"
    android:pivotY="300.0"
    android:rotation="45.0" >
    <path
      android:name="v"
      android:fillColor="#000000"
      android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
  </group>
</vector>

在矢量动画中,引用矢量图定义的名字:

<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:drawable="@drawable/vectordrawable" >
  <target
    android:name="rotationGroup"
    android:animation="@anim/rotation" />
  <target
    android:name="v"
    android:animation="@anim/path_morph" />
</animated-vector>

以下例子代表了一个 ObjectAnimator or AnimatorSet 对象:动作为旋转360度

<!-- res/anim/rotation.xml -->
<objectAnimator
  android:duration="6000"
  android:propertyName="rotation"
  android:valueFrom="0"
  android:valueTo="360" />

下面的例子表示矢量图path从一个图形到另一个。两种渐变路径必须一致:他们必须具有相同数量的命令和相同数量的每个命令的参数:

<!-- res/anim/path_morph.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <objectAnimator
    android:duration="3000"
    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" />
</set>
(0)

相关推荐

  • Material Design系列之Behavior实现Android知乎首页

    本博客目的:仿知乎首页向上滑动时动画隐藏Toolbar.FlocationActionButton.Tab导航,下滑时显示,如果和你的期望不同,那么你可以不需要看了,免的浪费你的宝贵时间噢. 效果预览 知乎效果: 本博客实现效果: 今天效果的源代码下载链接在文章末尾. 实现分析 这个效果其实并不难实现,但是它的用处很大,当用户手指上滑,屏幕上显示下方内容的时候,隐藏Toolbar.Tab导航.FAB来腾出更大的空间显示内容,让用户爽.简单粗暴,但这就是我们的目的. 首先就是头部的Toolbar,

  • 学习使用Material Design控件(四)Android实现标题栏自动缩放、放大效果

    本文要实现内容移动时,标题栏自动缩放/放大的效果,效果如下: 控件介绍 这次需要用到得新控件比较多,主要有以下几个: CoordinatorLayout 组织它的子views之间协作的一个Layout,它可以给子View切换提供动画效果. AppBarLayout 可以让包含在其中的控件响应被标记了ScrollingViewBehavior的View的滚动事件 CollapsingToolbarLayout 可以控制包含在CollapsingToolbarLayout其中的控件,在响应colla

  • Android构建Material Design应用详解

    长久以来.Android的UI并不算美观,以至于很多IT公司在进行界面设计的时候,为了保证双平台的统一性,强烈要求Android端的界面风格必须与iOS端一致,我认为这里非常不合理的,同一操作系统中各个应用之间的界面统一性要远比一个应用在双平台的界面统一性重要的多,只有这样,才能给使用者带来更好的用户体验.为了解决这个问题,Google公司在2014年IO大会上推出了一套全新的界面设计语言--Material Design(材料设计语言),这次Google在界面设计上确实下足了功夫,一个词,好看

  • Android App仿QQ制作Material Design风格沉浸式状态栏

    一.概述 近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下效果图: 恩,接下来正题. 首先只有大于等于4.4版本支持这个半透明状态栏的效果,但是4.4和5.0的显示效果有一定的差异,所有本文内容为: 1.如何实现半透明状态栏效果在大于4.4版本之上. 2.如何让4.4的效果与5.0的效果尽可能一致. 先贴下模拟器效果图,以便和实现过程中做下对比 4.4 模拟器 5.x 真机 二.实现半透明状态栏 因为本例使用了NavigationView,所以布局代码稍多,当然如果你不需要,可以自己进行筛

  • 学习Android Material Design(RecyclerView代替ListView)

    本文实例实现一下 RecyclerView,代码比较简单,适合初学者,如有错误,欢迎指出. 复习 ListView 可以查看这篇文章深入浅出学习Android ListView基础,了解关于ListView 的基础知识. 实现过程中需要复写BaseAdapter,主要是这4个方法 public int getCount() :适配器中数据集中 数据的个数,即ListView需要显示的数据个数 public Object getItem(int position) : 获取数据集中与指定索引对应的

  • Android5.0中Material Design的新特性

     Material Design简介 Material Design是谷歌新的设计语言,谷歌希望寄由此来统一各种平台上的用户体验,Material Design的特点是干净的排版和简单的布局,以此来突出内容. Material Design对排版.材质.配色.光效.间距.文字大小.交互方式.动画轨迹都做出了建议,以帮助设计者设计出符合Material Design风格的应用. Material Design设计语言鼓励大家使用充满活力的鲜艳色彩,并在同一界面建议使用三种色调,并保障有一个强色调,

  • 详解Android Material Design自定义动画的编写

    新的动画Api,让你在UI控件里能创建触摸反馈,改变View的状态,切换activity的一系列自定义动画 具体有: 响应View的touch事件的触摸反馈动画 隐藏和显示View的循环展示动画 两个Activity间的切换动画 更自然的曲线运动的动画 使用View的状态更改动画,能改变一个或多个View的属性 在View的状态更改时显示状态列表动画 这些new animations Api,已内置在标准Widget中,如Button.在自定义view时也可使用这些api 动画在Material

  • 详解Android如何实现自定义的动画曲线

    目录 前言 Curve 类定义 实例解析 正弦动画曲线 总结 前言 最近在写动画相关的篇章,经常会用到 Curve 这个动画曲线类,那这个类到底怎么实现的?如果想自己来一个自定义的动画曲线该怎么弄?本篇我们就来一探究竟. 曲线 Curve 类定义 查看源码, Curve 类定义如下: abstract class Curve extends ParametricCurve<double> {   const Curve();   @override   double transform(dou

  • 详解Android Material设计中阴影效果的实现方法

    View可以投下的阴影,一个View的elevation值决定了它的阴影的大小和绘制的顺序.可以设置一个视图的elevation,在布局中使用属性:android:elevation <TextView android:id="@+id/my_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=&quo

  • 详解Android如何自定义view实现圆形进度条

    Android中实现进度条有很多种方式,自定义进度条一般是继承progressBar或继承view来实现,本篇中讲解的是第二种方式. 先上效果图: 实现圆形进度条总体来说并不难,还是跟往常一样继承view,初始化画笔,按下面的步骤一步步来就好了.对初学者来说动画效果可能比较陌生,我们可以使用属性动画中的valueAnimator来实现动画效果. 实现步骤: 1.画出一个灰色的圆环作为背景. 2.画出上层的圆环覆盖下方的圆环. 3.加入动画效果 值得注意的是怎么设置圆环和文字的位置. 画出矩形只需

  • 详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题

    详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题 今天在项目中实现了一个效果,主要是画一个圆.为了后续使用方便,将这个圆封装在一个自定义Actor(CircleActot)中,后续想显示一个圆的时候,只要创建一个CircleActor中即可. 部分代码如下所示: package com.ef.smallstar.unitmap.widget; import android.content.res.Resources; import

  • 详解Android如何实现阴影效果

    目录 实现形式 elevation CardView属性 shadow属性 layer配置文件 自定义实现 小结 实现形式 elevation Material Design提供了View的阴影效果设置.主要由两个属性决定:elevation和translationZ. Z = elevation + translationZ PS:这种实现方式只有API21以及以上才能支持实现. elevation属性表示View高度加上高度就会有阴影效果. translationZ属性表示给View增加一个

  • 详解Android更改APP语言模式的实现过程

    一.效果图 二.描述 更改Android项目中的语言,这个作用于只用于此APP,不会作用于整个系统 三.解决方案 (一)布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" a

  • Android Material Design 阴影实现示例

    本文介绍了Android Material Design 阴影实现示例,分享给大家,具体如下: 让 View 产生阴影有以下 4 种方式: 控制 elevation 使用 OutlineProvider 使用 9 图 使用 MD 风格的控件,如 CardView,FloatingActionButton 0.Z轴的概念 Android 在 5.0 及以后采用了 Material Design 设计语言,引入了 Z 轴的概念,也就是垂直于屏幕的轴,Z 轴会让 View 产生阴影的效果: 想象有一束

  • 详解Android Studio实现用户登陆界面demo(xml实现)

    使用Android Studio 编写的第一个demo,使用布局文件-xml实现用户登录界面 注:所建工程均为Android 6.0 所以只要是Android 6.0(包括6.0)以上的真机,模拟机都可以使用 Step1:Android Studio 开发环境的搭建: 1.安装JDK (1.8): 2.安装Android studio (3.3.1) 包含 gradle.sdk manage .avd manage : 3.使用sdk manage 下载安装 sdk: 4.使用avd manag

  • 详解Android框架MVVM分析以及使用

    Android MVVM 分析以及使用 首先我们需要知道什么是MVVM,他的功能和优点,以及他的缺点. MVVM是Model-View-ViewModel的简写.它本质上就是MVC 的改进版.MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开.当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑.微软的WPF带来了新的技术体验,如Silverlight.音频.视频.3D.动画-

随机推荐