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. Oracle Dedicated server 和 Shared server(专用模式 和 共享模式) 说明(转)

    一.  官网说明 在DBCA 建库的时候,有提示让我们选择连接类型,这里有两种类型:专用服务器模式和共享服务器模式.默认使用专用模式.如下图: Oracle 官方文档对这两种文档的说明如下: Abou ...

  2. 17.1 Replication Configuration

    17.1 Replication Configuration 17.1.1 How to Set Up Replication 17.1.2 Replication Formats 17.1.3 Re ...

  3. 基于visual Studio2013解决C语言竞赛题之0514单词统计

     题目 解决代码及点评 /************************************************************************/ /* 14. 有一行字 ...

  4. 第一次PS练习

    嘿嘿,自己第一次的PS,虽然把在大神眼里是小KS,但是了,对我来说值得劲纪念.加油,我会努力的.

  5. 杭电OJ——1007 Quoit Design(最近点对问题)

    Quoit Design Problem Description Have you ever played quoit in a playground? Quoit is a game in whic ...

  6. 搭建python集成开发环境.

    需要搭建的内容一共有三项, python ,wxpython 以及spe.     其中spe 是python 的可视化集成开发环境(ide) , 其需要python GUI图形库wxpython的支 ...

  7. Ch06 验证

    6.1  服务器端验证 6.1.1  Data Annotations验证 6.1.2  扩展ModelMetadtaProvider 6.2  客户端验证 6.2.1  客户端验证初步 6.2.2  ...

  8. 网盘大全, 邮箱大全 good

    网盘推荐 115网盘 注册 百度网盘 注册 微云 注册 360云盘 注册 金山快盘 注册 新浪微盘 注册 和彩云 注册 酷盘 注册 OneDrive 外链 BOX 注册 Dropbox 注册 国内网盘 ...

  9. 基于visual Studio2013解决C语言竞赛题之1012连接字符串

         题目 解决代码及点评 /* 编写一个函数JOIN,让它实现字符串连接运算功能. */ #include <stdio.h> #include <stdl ...

  10. Adrnoid开发系列(二十五):使用AlertDialog创建各种类型的对话框

    AlertDialog能够生成各种内容的对话框.可是每种对话框都会有这样的的结构: 类似下边这样的的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTA ...