Android L带来了许多新特性,其中就包括了大量的动画效果,你可以在自己的应用中使用。本文中我将详解这些动画和如何在应用中使用。本文中的所有代码可以在github上找到。

波纹和强调

现在安卓支持少量的预定义样式属性,不过只限于应用特定部分例如状态栏、导航栏。新系统允许我们采用简单的方式即可获得两种非常简洁、有用的动画:波纹和被强调的UI组件。波纹是一种给予用户在UI上动作极好的回应效果,并且可以自定义波纹的颜色,只需要给colorControlHighlight 属性设置色值。

1
<item name="android:colorControlHighlight">#0000AA</item>

Ripples

一样简单,很多UI组件像复选框都可以使用styles文件夹中的colorAccent 属性来设置符合你应用主题的颜色,而不必使用不同的图片和状态选择器。

1
<item name="android:colorAccent">#00FF00</item>

圆形显示

安卓中一件常见工作就是改变屏幕上某一元素的可见性。现在开发者又多了一个选择可以让这项工作完成的更加漂亮:圆形显示。使用ViewAnimationUtil.createCircularReveal方法然后通过动画监听在合适的时间改变View的可见性。这有两个相似的方法用来让View可见或者消失。注意显示方法有一个持续时间的设置,以便完成动画的显示,隐藏动画执行的更快一点。getX()和getY()方法返回图片所在X、Y轴的中心点的坐标,getRadius()方法就是返回View的宽度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
private void hideImageCircular() {
    int x = getX();
    int y = getY();
    int radius = getRadius();
 
    ValueAnimator anim =
            ViewAnimationUtils.createCircularReveal(mImageView, x, y, radius, 0);
 
    anim.addListener(new AnimatorListenerAdapter() {
 
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            mImageView.setVisibility( View.INVISIBLE );
        }
    });
 
    anim.start();
}
 
private void revealImageCircular() {
    int x = getX();
    int y = getY();
    int radius = getRadius();
 
    ValueAnimator anim =
            ViewAnimationUtils.createCircularReveal(mImageView, x, y, 0, radius);
 
    anim.setDuration( 1000 );
    anim.addListener( new AnimatorListenerAdapter() {
        @Override
        public void onAnimationStart(Animator animation) {
            super.onAnimationStart(animation);
            mImageView.setVisibility( View.VISIBLE );
        }
    });
 
    anim.start();
}

Circular Reveal

Activity转场动画

除了前述几种动画,android L还增加了一些activity的过渡动画——爆炸、滑动、淡入淡出,让应用更加平滑。使用这些动画,你必须在进入和退出activity都要求使用这些内容转场特效,并且在setOncontent()方法之前。

1
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

也支持通过样式设置转换动画,我将详解如何在activity中通过样式设置专场效果。使用getWindow().setExitTransition( Transition ) 和getWindow().setEnterTransition( Transition ) 方法告诉activity当打开和关闭时如何执行。使用迸发动画,从MainActivity和ListFragment 到第二个activity的代码可以这样写:

1
2
3
4
ListFragment:
getActivity().getWindow().setExitTransition( new Explode() );
intent = new Intent( getActivity(), ExplodeAnimationActivity.class );
startActivity( intent );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ExplodeAnimationActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    getWindow().setEnterTransition( new Explode() );
    getWindow().setExitTransition( new Explode() );
    setContentView(R.layout.activity_explode_animation);
}
 
@Override
public void onBackPressed() {
    super.onBackPressed();
    finishAfterTransition();
}

注意onBackPressed()方法——这很重要。因为它让操作系统知道在关闭第二个activity之前要完成动画的执行。使用这些简单的代码,我们就拥有了三种activity专场动画。

Explosion Transition

Slide Transition

Fade Transition

虽然我没有用到这个非常有用的工具,但是应当引起注意的是专场动画监听——Transition.TransitionListener。使用监听可以在进入和退出动画生命周期中的特定点执行一些操作,给你更多让应用如何表现的控制权。为了防止内容泄漏,需要在Ondestory()方法中移除监听。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
getWindow().getEnterTransition().addListener( new Transition.TransitionListener {
    @Override
    public void onTransitionStart(Transition transition) {
 
    }
 
    @Override
    public void onTransitionEnd(Transition transition) {
 
    }
 
    @Override
    public void onTransitionCancel(Transition transition) {
 
    }
 
    @Override
    public void onTransitionPause(Transition transition) {
 
    }
 
    @Override
    public void onTransitionResume(Transition transition) {
 
    }
});

Activity专场动画之元素共享

除了标准的过渡动画,现在支持在两个activity过渡动画过程中共享元素。第一件要做的就是设置activity,使用内容转场动画并且允许覆盖转场动画。可以通过样式来设置:

1
2
3
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowExitTransitionOverlap">true</item>

元素共享动画也可以在代码中设置,此例中,我将使用样式来完成:

1
2
<item name="android:windowSharedElementEnterTransition">@transition/changebounds</item>
<item name="android:windowSharedElementExitTransition">@transition/changebounds</item>

Changebounds转场动画被定义以xml文件的形式存放在资源文件中。注意,我增加了两位两个属性:时长和插值器,让动画更有趣。

1
2
3
4
5
changebounds.xml:
<changeBounds
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:interpolator="@android:interpolator/bounce" />

下一步就是,确定在两个activity的布局文件中都使用实现Comparable接口的View类型(此例中使用ImageView),并且他们的viewName 属性值必须相同。在第一个activity中具有共享元素的View是这样的:

1
2
3
4
5
<ImageView
    android:id="@+id/image"
    android:viewName="image"
    android:layout_width="match_parent"
    android:layout_height="250dp" />

第二个activity中的是这样的:

1
2
3
4
5
6
<ImageView
    android:id="@+id/image"
    android:layout_alignParentBottom="true"
    android:viewName="image"
    android:layout_width="match_parent"
    android:layout_height="250dp" />

既然所有的xml设置都准备好了,我们可以开始在执行动画的activity中写代码了。在第一个activity中我们设置父类容器视图setTransitionGroup为false,然后获取我们想要共享元素的ImageView的drawable,把它转变为字节流对象放到intent的bundle中。然后,为ImageView使用场景动画转换创建ActivityOptions 对象,开启下一个activity。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Intent intent = new Intent( this, SharedElementSecondAnimationActivity.class );
 
((ViewGroup) mImageView.getParent()).setTransitionGroup( false );
 
ByteArrayOutputStream stream = new ByteArrayOutputStream();
( (BitmapDrawable) mImageView.getDrawable() ).getBitmap().compress(Bitmap.CompressFormat.PNG, 100, stream);
intent.putExtra( "image", stream.toByteArray() );
 
ActivityOptions options;
 
try {
    options = ActivityOptions.makeSceneTransitionAnimation( this, mImageView, "image" );
} catch( NullPointerException e ) {
    Log.e( "SharedElementAnimationChangeBoundsActivity", "Did you set your ViewNames in the layout file?" );
    return;
}
 
if( options == null ) {
    Log.e("sharedelementanimation", "Options is null. Something broke. Good luck!");
} else {
    startActivity(intent, options.toBundle());
}

在第二个activity中,从Intent的bundle中读取字节流并解码为bitmap对象,然后把它设置到Imageview上。第二个activity也重写了onBackPressed()方法,为了当返回键按下的时候执行退出动画。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shared_element_second_animation);
    mImageView = (ImageView) findViewById( R.id.image );
 
    byte[] byteArray = getIntent().getByteArrayExtra("image");
    Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    mImageView.setImageBitmap(bitmap);
}
 
@Override
public void onBackPressed() {
    super.onBackPressed();
    finishAfterTransition();
}

基于以上这些我们完成了共享元素转换动画,在第二个activity中共享元素被移动到新的位置,并且有一个回弹效果。

这几个动画的例子仅是android L的冰山一角,而且没有涉及Kit Kat中引入的场景动画。我希望这篇教程帮助其他开发者学习到新的东西,使用动画让应用不但好看而且有趣。

Android L动画入门的更多相关文章

  1. [转]ANDROID L——Material Design详解(动画篇)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 转自:http://blog.csdn.net/a396901990/article/de ...

  2. ANDROID L——Material Design具体解释(动画篇)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

  3. android 开发从入门到精通

    Android-Tips This is an awesome list of tips for android. If you are a beginner, this list will be t ...

  4. 【前端优化之渲染优化】大屏android手机动画丢帧的背后

    前言 上周我与阿里的宇果有一次技术的交流,然后对天猫H5站点做了一些浅层次的分析,后面点时间基本天天都会有联系,中途聊了一些技术细节.聊了双方团队在干什么,最后聊到了前端优化.因为我本身参与了几次携程 ...

  5. ANDROID L——Material Design详解(UI控件)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

  6. Android Wear 开发入门

    大家好,我是陆嘉杰,我是一名Android开发者.我想和大家进行一些技术交流,希望越来越多的人能和我成为好朋友. 大家都知道,智能手表是下一个开发的风口,而这方面的技术又属于前沿,所以和大家分享下An ...

  7. Android 开机动画源码分析

    Android系统在启动SystemServer进程时,通过两个阶段来启动系统所有服务,在第一阶段启动本地服务,如SurfaceFlinger,SensorService等,在第二阶段则启动一系列的J ...

  8. ANDROID L——Material Design综合应用(Demo)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Material Design: Material Design是Google推出的一个全 ...

  9. ANDROID L——Material Design详细解释(UI控制)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

随机推荐

  1. Microsoft Visual Studio 发展历史

    Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品.VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代码管控工具. ...

  2. poj 3370 鸽笼原理知识小结

    中学就听说过抽屉原理,可惜一直没机会见识,现在这题有鸽笼原理的结论,但其实知不知道鸽笼原理都可以做 先总结一下鸽笼原理: 有n+1件或n+1件以上的物品要放到n个抽屉中,那么至少有一个抽屉里有两个或两 ...

  3. yii_wiki_145_yii-cjuidialog-for-create-new-model (通过CJuiDialog来创建新的Model)

    /**** CJuiDialog for create new model http://www.yiiframework.com/wiki/145/cjuidialog-for-create-new ...

  4. Git学习笔记总结和注意事项

    一.Git简单介绍 Git是眼下世界上最先进的分布式版本号控制系统.其特点简单来说就是:高端大气上档次! 二.Windows上Git安装 最早Git是在Linux上开发的.非常长一段时间内.Git也仅 ...

  5. stm32之CAN总线基础

    can总线协议概述: CAN是Controller Area Network的缩写,由德国博世公司开发:CAN通过ISO11891以及ISO11519进行了标准化:     CAN总线的特点: 1.多 ...

  6. 安装apk程序进android

    package com.example.installmyapk; import java.io.File; import android.net.Uri; import android.os.Bun ...

  7. 2015.7.17( NOI2015 day1 )

    今天早起做了NOI2015网络同步赛.... 最近NOI是越来越向NOIP靠拢了....但是我还是不会做..... 第一题:程序自动分析 先离散化一下..然后最多就剩20w个数 , 不等于就存起来.. ...

  8. sencha touch笔记(5)——DataView组件(1)

    1.DataView组件可以显示列表,图像等等的组件或者元素,特别适用于数据仓库频繁更新的情况.比如像显示新闻或者微博等等的很多相同样式的组件的列表这种一次性从后台或者数据源拿取很多数据展示的样式.比 ...

  9. 一口一口吃掉Hibernate(八)——Hibernate中inverse的用法

    一.Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之 ...

  10. 【转】[Mysql] Linux Mysql 日志专题

    原文链接:http://blog.csdn.net/xiaoxu0123/article/details/6258538 1, 设置存放的目录: [root@Linux etc]# more /etc ...