ApiDemos之activity切换动画

来源:互联网 发布:4g逛淘宝用多少流量 编辑:程序博客网 时间:2024/04/30 23:14

上一篇我们说道了Android apidemos导入的一些相关问题。现在这些demo已经成功导入了Android studio里,接下来我们就要认真分析这些demo了,我们以最新的23版本为标准,先从最简单的activity说起吧。下面我们开始分析app/activity下的第一个demo—-Animaition

Animaition是什么?

Animaitionc就是动画,在Android中Animaition很基本可以分为:以下几种

  • Tween Animation(补间动画) 只能对View对象进行操作,不对view有任何实际的改变
  • Frame Animation(帧动画)由一组图像顺序显示显示动画
  • Property Animation(属性动画)补间动画加强版,不局限于view,并可以真正的改变属性等

今天我们只关注activity的Animation。具体位置在app->Animaition.java。

先来看一段代码

Button button = (Button)findViewById(R.id.fade_animation);    button.setOnClickListener(mFadeListener);    button = (Button)findViewById(R.id.zoom_animation);    button.setOnClickListener(mZoomListener);if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {        button = (Button)findViewById(R.id.modern_fade_animation);        button.setOnClickListener(mModernFadeListener);        button = (Button)findViewById(R.id.modern_zoom_animation);        button.setOnClickListener(mModernZoomListener);        button = (Button)findViewById(R.id.scale_up_animation);        button.setOnClickListener(mScaleUpListener);        button = (Button)findViewById(R.id.zoom_thumbnail_animation);        button.setOnClickListener(mZoomThumbnailListener);        button = (Button)findViewById(R.id.no_animation);        button.setOnClickListener(mNoAnimationListener);    } else {        findViewById(R.id.modern_fade_animation).setEnabled(false);        findViewById(R.id.modern_zoom_animation).setEnabled(false);        findViewById(R.id.scale_up_animation).setEnabled(false);        findViewById(R.id.zoom_thumbnail_animation).setEnabled(false);    }

从这段代码中我们很清楚的看到,mFadeListener和mZoomListener是不区分版本的,但是其余的四个动画对Android的版本进行了区分,只有4.1以上的版本才可以使用。也就是是说要兼容更多的版本的话,要采用前两种动画的方式,这个我们最后在介绍。

首先看一下mModernFadeListener主要是做了什么

private OnClickListener mModernFadeListener = new OnClickListener() {    public void onClick(View v) {                   ActivityOptions opts = ActivityOptions.makeCustomAnimation(Animation.this,                R.anim.fade, R.anim.hold);        startActivity(new Intent(Animation.this, AlertDialogSamples.class), opts.toBundle());    }};    

代码很简单,只是通过ActivityOptions.makeCustomAnimation方法创建了一个ActivityOptions对象,然后在启动另一个activity的时候作为参数传递了进去,就完成了给activity设置动画的功能。那么什么是ActivityOptions呢?

ActivityOptions是Android 4.1(API16)提供的一个新类,用来实现Activity的切换动画,这也是为什么在前面要区分版本,因为只有API16之后才会有。

ActivityOptions类提供了三个方法

  • makeScaleUpAnimation() 创建一个动画,能够从屏幕指定的位置和指定的大小拉伸一个活动窗口。例如,当打开一个应用时,Android 4.1的主屏幕使用了这个方法。
  • makeThumbnailScaleUpAnimation() 创建一个动画,能够从屏幕指定的位置和提供的缩略图拉伸一个活动窗口。例如,在Android 4.1的最近使用程序窗口中,当往回一个应用程序时使用了这个动画。
  • makeCustomAnimation() 创建一个动画,由你自己的资源所定义:一个用来定义活动开启的动画,一个用来定义活动被关闭的动画。

  • 通过这三个方法中的一个就可以创建一个ActivityOptions示例,然后调用toBundle()方法获取一个Bundle对象,传递给startActivity方法。

接下来就是传递的两个xml文件了,我们简单看一下:

<alpha xmlns:android="http://schemas.android.com/apk/res/android"   android:interpolator="@android:anim/accelerate_interpolator"   android:fromAlpha="0.0" android:toAlpha="1.0"   android:duration="@android:integer/config_longAnimTime" />   

这是配置一个动画的xml文件,alpha节点表示这是一个透明的动画,属性的含义分别是:

  • interpolator 插入器 简单点说就是设置动画播放的速率
  • fromAlpha 动画开始的透明度
  • toAlpha 动画结束的透明度
  • duration 动画播放时间

为什么要传两个xml文件呢?相信聪明的朋友已经想到了,就是一个进入activity的动画,一个是离开的动画,我们看一下API就知道了

public static ActivityOptions makeCustomAnimation(Context context,        int enterResId, int exitResId) {    return makeCustomAnimation(context, enterResId, exitResId, null, null);}

enterResId和exitResId看名字就足以说明问题了,到这里我们就把一个activity的简单动画分析完了,但是我们需要注意的这在4.1前的版本版本是不适用的。

接下来看mModernZoomListener做了什么:

private OnClickListener mModernZoomListener = new OnClickListener() {    public void onClick(View v) {        ActivityOptions opts = ActivityOptions.makeCustomAnimation(Animation.this,                R.anim.zoom_enter, R.anim.zoom_enter);        startActivity(new Intent(Animation.this, AlertDialogSamples.class), opts.toBundle());    }};

这个和上面的基本上一样了,只是xml配置的动画不一样罢了,就不在赘述。继续看mScaleUpListener:

private OnClickListener mScaleUpListener = new OnClickListener() {    public void onClick(View v) {        ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(                v, 0, 0, v.getWidth(), v.getHeight());        startActivity(new Intent(Animation.this, AlertDialogSamples.class), opts.toBundle());    }};

这个就有意思了,没有用到xml文件,而是直接通过上面我们介绍到得makeScaleUpAnimation方法创建的,我们来看看makeScaleUpAnimation内部是怎么实现的

public static ActivityOptions makeScaleUpAnimation(View source,        int startX, int startY, int width, int height) {    ActivityOptions opts = new ActivityOptions();    opts.mPackageName = source.getContext().getPackageName();    opts.mAnimationType = ANIM_SCALE_UP;    int[] pts = new int[2];    source.getLocationOnScreen(pts);    opts.mStartX = pts[0] + startX;    opts.mStartY = pts[1] + startY;    opts.mWidth = width;    opts.mHeight = height;    return opts;}

先研究一下在调用这个方法的时候需要传入五个参数:

  • View source 动画作用的对象View,这里我们传入的其实就是button,所以动画会作用在button上
  • int startx 动画开始的X坐标
  • int starty 动画开始的Y坐标 这两个参数都是传的0,也是会从初始位置开始启动
  • int width 被拉伸view对象的初始宽度 这次我们直接传的就是view的宽度
  • int height 被拉伸view对象的初始高度 这次我们直接传的就是view的高度

其实makeScaleUpAnimation就是内部自己new一个ActivityOptions对象出来,然后把传入的参数传递给ActivityOptions而已,不过这里作用的对象是传入的View对象而不是activity哦。

最后要看的就是的就是mZoomThumbnailListener啦

 public void onClick(View v) {        v.setDrawingCacheEnabled(true); //激活绘制图形的缓存        v.setPressed(false);//取消按下的状态        v.refreshDrawableState();//刷新状态        Bitmap bm = v.getDrawingCache();//拿到绘制的图像        ActivityOptions opts = ActivityOptions.makeThumbnailScaleUpAnimation(                v, bm, 0, 0);        startActivity(new Intent(Animation.this, AlertDialogSamples.class), opts.toBundle());        v.setDrawingCacheEnabled(false);//关闭缓存    }

我们看到这次又是在View上进行了就地取材,拿到了view的图像然后传makeThumbnailScaleUpAnimation创建出一个ActivityOptions对象,从注释中我们基本了它都做了哪些操作,这个执行顺序是不能变的尤其是在
getDrawingCache之前一定要调用setDrawingCacheEnabled哦,否则就会拿到一个空的图像。接下来就是
makeThumbnailScaleUpAnimation了,我们只看它最终创建的地方

private static ActivityOptions makeThumbnailAnimation(View source,        Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,        boolean scaleUp) {    ActivityOptions opts = new ActivityOptions();    opts.mPackageName = source.getContext().getPackageName();    opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;    opts.mThumbnail = thumbnail;    int[] pts = new int[2];    source.getLocationOnScreen(pts);    opts.mStartX = pts[0] + startX;    opts.mStartY = pts[1] + startY;    opts.setOnAnimationStartedListener(source.getHandler(), listener);    return opts;}

其实makeThumbnailScaleUpAnimation最后调用的是makeThumbnailAnimation放大创建的对象,并且传入的listener为null和true来开启动画,帮我们省略了一些细节,简化了参数。其余的参数我们在上面已经介绍了,只不过这次作用是bitmap而不是view了,总的来说区别不大。

最后就是介绍一下版本通用的了

 public void onClick(View v) {        startActivity(new Intent(Animation.this, AlertDialogSamples.class));                   overridePendingTransition(R.anim.fade, R.anim.hold);    }

就是了overridePendingTransition方法了,传入两个xml文件就搞定了如果考虑到适配到低版本的话,优先考虑这种方式,而且不受限制。高版本的话当然建议选用ActivityOptions创建了。总的来说其实系统提供这些已经基本满足日常使用了,如果有特殊需求使用一些自定义动画即可,而随着Android手机硬件性能和系统性能的提高,切换动画的时间已经很短了,很难看出有很大区别了。

今天activity的切换动画就介绍到这里了,在实际开发过程中按照实际需求进行选择就好。

0 0
原创粉丝点击