Material Design,中文名:材料设计语言,是由Google推出的全新的设计语言,谷歌表示,这种设计语言旨在为手机、平板电脑、台式机和“其他平台”提供更一致、更广泛的“外观和感觉”。
Material Design语言的一些重要功能包括 系统字体Roboto的升级版本 ,同时颜色更鲜艳,动画效果更突出。谷歌的想法是让谷歌平台上的开发者掌握这个新框架,从而让所有应用就有统一的外观,就像是苹果向开发者提出的设计原则一样。谷歌还基于这种新的设计语言对本公司旗舰应用进行了重新设计,包括安卓和网页端的Gmail和Calendar。在安卓平台上,这种新界面被称为Material,支持各种新动画效果,具有内置的实时UI阴影,以及可在不同屏幕之间切换的hero元素。
展示
背景扩散从某一个点向四周展开或者从四周向某一点聚合起来,类似波纹的效果,可以给任意的View添加这种效果。 显示或隐藏一组 UI 元素时,揭露动画可为用户提供视觉连续性;可以用在 Activity 里面的 View 动画效果,用来揭露某个隐藏 View 的显示;也可以使用在 Activity 跳转过渡动画中。
展示
代码实现 :
Android Sdk 中已经帮我们提供了一个工具类 ViewAnimationUtils 来创建揭露动画。ViewAnimationUtils 里面只有一个静态方法 createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius), 返回一个 Animator 动画对象。
//第一个参数是执行揭露动画的 View 视图
//第二个参数是相对于视图 View 的坐标系,动画圆的中心的x坐标
//第三个参数是相对于视图 View 的坐标系,动画圆的中心的y坐标
//第四个参数是动画圆的起始半径,
//第五个参数动画圆的结束半径。
ViewAnimationUtils.createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int width = mImageView.getMeasuredWidth();
final int height = mImageView.getMeasuredHeight();
final float radius = (float) Math.sqrt(width * width + height * height);
//主要代码
Animator animator = ViewAnimationUtils.createCircularReveal(mImageView, width , height , radius, 0);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//mImageView.setVisibility(View.GONE);
}
});
animator.setDuration(2000);
animator.start();
}
});
曾经的Android在Activity进行跳转的时候,只是非常生硬的进行切换,即使用overridePendingTransition(int inId,int outId)这个方法来给Activity增加一些简单的切换动画。而在Android 5.X中,Google对动画效果进行了更深一步的诠释,为Activity的转场效果设计了更加丰富的动画效果。
Android 5.0之前使用overridePendingTransition(int inId,int outId)方法进行平移,旋转,缩放,淡入等简单动画
Android 5.0之后,加入1.explode(分解) ———从屏幕中间进或出,移动视图。2.slide(滑动)———从屏幕边缘进或出,移动视图。3.fade(淡出)———通过改变屏幕上视图的不透明度达到添加或移除的效果。
展示
代码实现 :
// 允许使用transitions
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
//分解
getWindow().setEnterTransition(new Explode());
getWindow().setExitTransition(new Explode());
//滑动
getWindow().setEnterTransition(new Slide());
getWindow().setExitTransition(new Slide());
//淡出
getWindow().setEnterTransition(new Fade());
getWindow().setExitTransition(new Fade());
getWindow().setEnterTransition(); //首次进入显示的动画
getWindow().setExitTransition(); //启动一个新Activity,当前页的退出动画
getWindow().setReturnTransition(); //调用 finishAfterTransition() 退出时,当前页退出的动画
getWindow().setReenterTransition(); //重新进入的动画。即第二次进入,可以和首次进入不一样。
startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
传统的在活动或者碎片之间的跳转是互相独立的,例如淡出,滑动以及新的explode(分解)跳转。然而很多时候在活动之间有共享元素提供了独立的注重连续性的去打破活动的边界的跳转。这些活动使人的眼睛更加专注于内容和新的活动的呈现使体验更加无缝化。
例如从一个Activity A转换到Activity B,他们共享一个元素(比如是一个view) 可以做一个平滑的过度,将共享的元素直接变换到最终的地方和大小,这会使用户专注于应用而且有一种连贯性的表达。
展示
代码实现
共享元素的连接点是所有共享元素View的transition name。通过transtion name来判断哪两个元素是共享关系
//代码设置
imageView. setTransitionName();
//共享单个元素跳转
Intent intent = new Intent();
intent.setClass(ExcessiveActivity.this, ExcessiveActivity2.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, imageView, "test").toBundle());
//共享多个元素跳转
Intent intent = new Intent(this,SecondActivity.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(imageView,"test"),
Pair.create(textview,"test2"));
startActivity(intent,options.toBundle());
注:一定要保证命名相同,这样系统才能找到共享元素
加载网络图片,在网络图片获取到之前,这个共享元素的动画效果没有作用。需要在图片下载完成之后在开始共享元素的动画效果,这个时候这个时候需要用到延时共享元素动画。
postponeEnterTransition()函数用于延时动画,startPostponedEnterTransition()函数用于开始延时的共享动画。在Activity进入的时候先调用postponeEnterTransition()延时动画,在网络图片获取完成之后在调用startPostponedEnterTransition()开始动画。
尽管添加延时可以让共享元素 Transition 更加流畅准确,但是应用中引入共享元素 Transition 的延迟还有一些副作用:延迟时间过长会在应用中产生不必要的卡顿,影响用户体验。
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excessive2);
imageView = findViewById(R.id.ImageView);
handler.sendEmptyMessageDelayed(0, 1000);
postponeEnterTransition();//停止动画
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
imageView.setImageResource(R.drawable.timg);
startPostponedEnterTransition();//开始动画
}
};
曲线运动是动画利用曲线实现时间内插与空间移动模式, PathInterpolator是一个基于贝塞尔曲线或path对象的全新插入器,这个插入器会在1*1的正方形内指定一个运动曲线,定位点位于(0,0)以及(1,1),而控制点由构造函数参数指定。属性动画类别给出了新的构造函数,可以使用path对象为视图的X,Y属性添加动画,系统提供了三种基本曲线:
除此之外可以自己定义:根据需要的曲线去绘制,其实跟我们使用的贝塞尔曲线去不断刷新视图的运动轨迹是一样的。
//TODO 使用曲线运动
private void doCurdAnimation(View view) {
Path path = new Path();
path.arcTo(1f, 1f, 400f, 800f, 0, 90, false);
PathInterpolator pathInterpolator = new PathInterpolator(1, 1);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
objectAnimator.setInterpolator(pathInterpolator);
objectAnimator.setDuration(3000);
objectAnimator.start();
}
SVG 是使用 XML 来描述二维图形和绘图程序的语言。可伸缩矢量图形,图片在放大或者改变尺寸的情况下其图形质量不会有所损失
Google在Android5.X中提供了VectorDrawable AnimatedVectorDrawable两个新的API来帮助支持SVG:
SVG中
VectorDrawable
创建一个静态矢量图 vector.xml
其中包含两组宽高属性,height、width和viewportHeight、viewportWidth。这两组属性分别具有不同的含义,height、width表示该SVG图形的具体大小,而viewportHeight、viewportWidth表示SVG图形划分的比例。后面在绘制path时所使用的参数,就是根据这两个值来进行转换的,比如上面的代码,将200dp划分为100份,如果在绘制图形时使用坐标(50,50),则意味着该坐标位于该SVG图形正中间。因此,height、width的比例与viewportHeight、viewportWidth的比例,必须保持一致,不然图形就会发生压缩、形变。
通过添加
AnimatedVectorDrawable
AnimatedVectorDrawable的作用是给VectorDrawable提供动画效果,Google将AnimatedVectorDrawable比喻一个胶水,通过AnimatedVectorDrawable来连接静态的VectorDrawable和动态的objectAnimator。
创建具有动画效果的矢量图 anim_vector.xml
对应的vector中 android:drawable="@drawable/verctor" 即为静态的矢量图。target 中 android:animation="@animator/anim_rotate" 代表的是动画效果,采用objectAnimator
动画启动方式:
final ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageResource(R.drawable.anim_vector); // 设置Resource为动画资源
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animatable anim = (Animatable)imageView.getDrawable();
anim.start(); // 开始动画
}
});
完结