MD动画是谷歌推出的一种动画效果,其实现的效果能让用户看着很是舒服,符合MD动画的动画,有很强的用户交互体验

Touch Feedback(触摸反馈)

在触摸反馈这一块,用的最多的就是水波纹效果,而水波纹效果是从5.0才开始出现的,从5.0开始,便已自带水波纹效果

以下是一个水波纹的按钮示例

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="自带效果" /> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:text="系统效果 有边界" /> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:text="系统效果 无边界" /> </LinearLayout>

其效果如下



可以明显看出,不使用系统属性的button自带水波纹效果,这主要是由于使用了AppCompat的主题的原因,当然,也可以在主题中修改背景和水波纹的颜色

<item name="colorControlHighlight">?attr/colorPrimary</item>
<item name="colorControlNormal">@android:color/holo_orange_light</item>

在使用AppCompat主题的时候,Activity最好也使用AppCompatActivity,可以实现更好的兼容

上面的例子可以看出selectableItemBackground是不带按钮边界的,但在点击时候会后水波纹,长按时会显示出轮廓,selectableItemBackgroundBorderless也没有轮廓,长按时会显示出圆形,圆的大小与控件的宽高最大值匹配

Reveal Effect(揭露效果)

比如Activity的揭露出现的效果,需要使用ViewAnimationUtil工具类来设置View

比如要实现一个水波纹揭露效果,那么需要操作的View,扩散的中心点,开始的扩散半径,结束的扩散半径,函数原型如下

ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius)

这里扩散一个按钮作为示例

布局就只有一个按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"> <Button
android:id="@+id/button"
android:onClick="revealAnimation"
android:layout_width="100dp"
android:layout_height="100dp" /> </LinearLayout>

然后实现其效果

public void revealAnimation(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Animator animator = ViewAnimationUtils.createCircularReveal(view, view.getWidth() / 2,
view.getHeight() / 2, 0,
(float) Math.hypot(view.getWidth(), view.getHeight()));
animator.setDuration(1000);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();
}
}

实现效果如下图

Activity transition(Activity转场动画效果)

要实现转场动画就需要使用到ActivityOptions,而这个类只支持5.0及以上版本,在v4包中有一个ActivityOptionsCompat,其作用一致,但在低于5.0的版本中,却无法实现转场动画,只是避免了在使用ActivityOptions时候的版本判断

不使用MD的转场动画例子

startActivity(new Intent(this, SecondActivity.class));
overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);

MD转场动画主要分为两大类:共享元素转换和普通转换

转场动画使用前提

要使用转场动画,就需要设置转场动画使用允许,例如A,B两个活动,从A到B的转场动画依赖于两个活动允许转场动画

设置转场动画方式:代码方式和主题方式,两种方法都可以实现

代码方式,这个是设置在setContentView()之前

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

主题方式

<item name="android:windowContentTransitions">true</item>

这里使用第一种,因为这样方便控制

共享元素转换

在不使用转场动画的时候,activity跳转默认效果如下



可以把两个Activity当中的相同的元素关联起来做连贯的变换动画

要实现共享元素的转换,就需要设置共享元素的元素名 使用android:transitionName属性设置其view名,两个元素名相同就可实现共享元素转换

这里实现了两个Activity,并且已经注册

FirstActivity布局及活动

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:id="@+id/first_image_view"
android:layout_width="200dp"
android:layout_height="300dp"
android:src="@drawable/image"
android:transitionName="iamge"
android:scaleType="centerCrop"
android:onClick="startSecondActivity"/> </LinearLayout>
public class First_Activity extends AppCompatActivity {
private ImageView imageView; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_first);
imageView = findViewById(R.id.first_image_view);
} public void startSecondActivity(View view) {
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(
this, imageView, "image");
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent, optionsCompat.toBundle());
}
}

SecondActivity布局及活动

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/image"
android:transitionName="iamge" /> </LinearLayout>
public class SecondActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_second);
}
}

实现效果图如下



按返回键的时候自动实现了返回的共享元素转场动画,这是在源代码中实现的

单个元素共享

ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this, imageView, "image");
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent, optionsCompat.toBundle());

多个元素共享

要使元素关联起来,例如FirstActivity中有ImageView和Button,分别设置为image,button,那么在SecondActivity中也要相应设置image和button

ActivityOptionsCompat optionsCompat = ActivityOptionsCompat
.makeSceneTransitionAnimation(this, Pair.create((View)imageView, "image"),Pair.create((View)button, "button"));
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent, optionsCompat.toBundle());

普通转场动画

普通转场动画主要有三种效果:滑动效果(Slide)、展开效果(Explode)、渐变显示隐藏效果(Fade)

这里使用一个跳转界面,复用跳转后的界面,实现转场动画,同时返回时候动画也与跳转动画相统一

跳转界面

public class NormalActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_normal);
} public void startSlide(View view) {
Slide slide = new Slide();
slide.setDuration(3000);
getWindow().setExitTransition(slide);
getWindow().setEnterTransition(slide);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
Intent intent = new Intent(this, NormalAnimActivity.class);
intent.setType("slide");
startActivity(intent, optionsCompat.toBundle());
} public void startExplode(View view) {
Explode explode = new Explode();
explode.setDuration(3000);
getWindow().setExitTransition(explode);
getWindow().setEnterTransition(explode);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
Intent intent = new Intent(this, NormalAnimActivity.class);
intent.setType("explode");
startActivity(intent, optionsCompat.toBundle());
} public void startFade(View view) {
Fade fade = new Fade();
fade.setDuration(3000);
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
Intent intent = new Intent(this, NormalAnimActivity.class);
intent.setType("fade");
startActivity(intent, optionsCompat.toBundle());
}
}

跳转界面布局

<?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"> <ImageView
android:id="@+id/first_image_view"
android:layout_width="200dp"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="@drawable/image" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Slide"
android:onClick="startSlide"/> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Explode"
android:onClick="startExplode"/> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Fade"
android:onClick="startFade"/>
</LinearLayout> </RelativeLayout>

展示界面

public class NormalAnimActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_normal_anim); String type = getIntent().getType();
switch (type){
case "slide":
Slide slide = new Slide();
slide.setDuration(3000);
getWindow().setExitTransition(slide);
getWindow().setEnterTransition(slide);
break;
case "explode":
Explode explode = new Explode();
explode.setDuration(3000);
getWindow().setExitTransition(explode);
getWindow().setEnterTransition(explode);
break;
case "fade":
Fade fade = new Fade();
fade.setDuration(3000);
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade);
break;
}
}
}

展示界面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/image" /> </LinearLayout>

为了更好的看见过程,这里设置的的动画时间有点长,设置为3秒

实现效果如下,图片有点大



如果有共享元素,可以设置共享元素,那么它就会按照共享元素动画执行,其他的子view就会按照Fade动画执行

高级UI-MD动画的更多相关文章

  1. Android 高级UI设计笔记07:RecyclerView 的详解

    1. 使用RecyclerView       在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...

  2. firefox 扩展开发笔记(三):高级ui交互编程

    firefox 扩展开发笔记(三):高级ui交互编程 前言 前两篇链接 1:firefox 扩展开发笔记(一):jpm 使用实践以及调试 2:firefox 扩展开发笔记(二):进阶开发之移动设备模拟 ...

  3. 编程实战——电影管理器之界面UI及动画切换

    编程实战——电影管理器之界面UI及动画切换 在前文“编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息”中提到电影管理器的目的是方便播放影片,在想看影片时不需要在茫茫的文件夹下找 ...

  4. html5 canvas高级贝塞尔曲线运动动画(好吧这一篇被批的体无完肤!都说看不懂了!没办法加注释了!当然数学不好的我也没办法了,当然这还涉及到一门叫做计算机图形学的学科)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 一款基于jquery ui的动画提交表单

    今天要给大家分享一款基于jquery ui的动画提交表单.这款提交表单的的效果是以动画的形式依次列表所需填写的信息.效果非常不错,效果图如下: 在线预览   源码下载 实现的代码. html代码: & ...

  6. iOS开发——高级UI&带你玩转UITableView

    带你玩装UITableView 在实际iOS开发中UITableView是使用最多,也是最重要的一个控件,如果你不会用它,那别说什么大神了,菜鸟都不如. 其实关于UItableView事非常简单的,实 ...

  7. 高级UI晋升之自定义View实战(六)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从Android 自定义属性动画&Camera动画来介绍自定义V ...

  8. 高级UI晋升之常用View(三)中篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从ViewPager来介绍常用View:文章目录 一.简介 二.基本使用 ...

  9. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

  10. Android 高级UI设计笔记08:Android开发者常用的7款Android UI组件(转载)

    Android开发是目前最热门的移动开发技术之一,随着开发者的不断努力和Android社区的进步,Android开发技术已经日趋成熟,当然,在Android开源社区中也涌现了很多不错的开源UI项目,它 ...

随机推荐

  1. 【一起来烧脑】底层HTTP深入笔记

    [外链图片转存失败(img-0GQ8QDNb-1563568792102)(https://upload-images.jianshu.io/upload_images/11158618-5bc7a2 ...

  2. SDOI2015做题记录

    由于我懒,并且这里面除了D2T3恶心以外都不难写,所以很多代码都没写-- 排序 对于某一个合法的操作序列(操作序列定义为每次交换的两组数),可以随意交换顺序,仍然合法.所以对于一个操作集合,答案就加\ ...

  3. npm start的时候改变端口及组合脚本

    windows npm修改端口启动 set PORT=3000&&roadhog server npm start Linux npm 修改端口启动 set PORT=3000 roa ...

  4. UDP 区别于 TCP 的特点

    TCP 我们了解得多了,所以今天我们站在 UDP 的角度,探讨一下 UDP 区别于 TCP 的特点. 1. 面向无连接 UDP 比 TCP 简单得多,不需要“三次握手”来建立连接,直接把内容发送出去. ...

  5. HTML meta pragma no-cache 页面缓存

    HTML meta pragma no-cache 页面缓存不缓存页面(为了提高速度一些浏览器会缓存浏览者浏览过的页面,通过下面的定义,浏览器一般不会缓存页面,而且浏览器无法脱机浏览.) <me ...

  6. C++多重继承分析——《虚继承实现原理(虚继承和虚函数)》

    博客转载:https://blog.csdn.net/longlovefilm/article/details/80558879 一.虚继承和虚函数概念区分 虚继承和虚函数是完全无相关的两个概念. 虚 ...

  7. 重写mybatis的字符串类型处理器

    1.简介 无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型. St ...

  8. mpvue开发坑点总结

    最近一直在开发微信小程序,趁着空闲时间总结下使用情况. 现在项目目前使用的是 mpvue:^1.0.11 版本,后续看看更新情况. 文档在此: http://mpvue.com/mpvue/#_2 # ...

  9. 关于aes加密

    aes加密有几种模式:CBC,AES-128bit, Pkcs7补码方式(后台有可能是PKCS5Padding,是一样的),安卓和ios的key密钥对长度没有要求,但是前端web的密钥和偏移量必须是1 ...

  10. book-rev8

    xv6 a simple, Unix-like teaching operating system 一个简易.类Unix教学操作系统 Russ Cox Frans Kaashoek Robert Mo ...