Android位移动画之——TranslateAnimation实现大师哥运送快递动画

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17475155/article/details/52062423

一、背景

Android中的动画效果是一个非常强大的功能,在使用过程中极大地提高的用户的视觉以及操作体验,Animations是一个实现Android UI 界面动画效果的API,Animation提供了一系列最基本的动画效果,可以包含旋转,缩放,淡入淡出等等,而Android中大多数控件都可以应用到这些动画。

二、分类

Android的动画大致分为补间动画(Tween Animation)、帧动画((Frame Animation)以及属性动画(PropertyAnimation)

补间动画

a. 渐变动画支持四种类型:平移(Translate)、旋转(Rotate)、缩放(Scale)、不透明度(Alpha)。

b. 只是显示的位置变动,View的实际位置未改变,表现为View移动到其他地方,点击事件仍在原处才能响应。

c. 组合使用步骤较复杂。

d. ViewAnimation 也是指此动画。

l  帧动画(FrameAnimation)

a. 用于生成连续的Gif效果图。

b.DrawableAnimation也是指此动画。

l  属性动画(Property Animation)

a. 支持对所有View能更新的属性的动画(需要属性的setXxx()和getXxx())。

b. 更改的是View实际的属性,所以不会影响其在动画执行后所在位置的正常使用。

c.Android3.0 (API11)及以后出现的功能,3.0之前的版本可使用github第三方开源库nineoldandroids.jar进行支持。

 

三、位移动画TranslateAnimation

Translate动画非常好理解,就是定义一个开始的位置和一个结束位置,定义移动时间,然后就能自动产生移动动画。Androidtranslate移动方向有 横向(X) 竖向(Y), 左右滑动使用了横向移动效果。

TranslateAnimation作为Android JDK提供给开发者的API,共有三个构造函数分别是:

a.    TranslateAnimation(Contextcontext,AttributeSet attrs) , 最基础的构造方法基本不用

b.     TranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta)这是最常用也是相对简单的一个方法,其中参数代表的内容分别为:

float fromXDelta:动画在X轴上的相对起始位置;

float toXDelta:动画在X轴上的相对结束位置;

float fromYDelta:动画在Y轴上的相对起始位置;

float toYDelta):动画在X轴上的相对结束位置;

 

举例:如果viewA(x,y)那么动画就是从B(x+fromXDelta, y+fromYDelta)点移动到C(x+toXDelta,y+toYDelta).

c.    TranslateAnimation(intfromXType, float fromXValue, int toXType, float toXValue, int fromYType, floatfromYValue, int toYType, float toYValue) 这个方法常用也是本例中使用的一个方法,为什么要使用这个方法在项目步骤中我会提到。

 

fromXType:第一个参数是x轴方向的值的参照(Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF,orAnimation.RELATIVE_TO_PARENT),其中,Animation.ABSOLUTE,对应的值应该是具体的坐标值,比如0到100,指绝对的屏幕像素单位;Animation.RELATIVE_TO_SELF或者Animation.RELATIVE_TO_PARENT指的是相对于自身或父控件,对应值应该理解为相对于自身或者父控件的几倍或百分之多少;

fromXValue:毫无疑问就是在X轴的起始值以此类推。

 

四、项目实例

大师哥APP中实现效果:


大概意思就是运用夸张的手法来描述运送快递的速度很快快-.-,好吧这里略过不解释直接看代码


项目原本是基于eclipse来开发的,登录界面除了动画以外还涉及登陆的相应方法比较繁重因此为了更加方便演示在Android studio上新建一个工程移植过来

1)activity_main.xml 首先是布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.ricahrd.translateanimation.MainActivity">



    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="225dp"
        android:background="#22aaee" >

        <ImageView
            android:id="@+id/iv_login_moon"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_moon" />

        <ImageView
            android:id="@+id/iv_login_build03"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_build03" />

        <ImageView
            android:id="@+id/iv_login_build01"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_build01" />

        <ImageView
            android:id="@+id/iv_login_build02"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_build02" />

        <ImageView
            android:id="@+id/iv_login_tree"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_tree" />

        <ImageView
            android:id="@+id/iv_login_tree01"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_tree" />

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignTop="@+id/iv_login_build01"
            android:layout_marginLeft="46dp"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_car_01" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/iv_login_tree"
            android:layout_alignParentRight="true"
            android:layout_marginRight="59dp"
            android:contentDescription="@null"
            android:src="@drawable/bm_login_bg_car_02" />

        <ImageView
            android:id="@+id/iv_login_packeg1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/imageView2"
            android:layout_toLeftOf="@+id/imageView2"
            android:src="@drawable/bm_login_packeg" />

        <ImageView
            android:id="@+id/iv_login_packeg2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/imageView1"
            android:layout_alignTop="@+id/imageView2"
            android:src="@drawable/bm_login_packeg" />

    </RelativeLayout>



</RelativeLayout>
效果如图:


2)MainAcitivity.class

在效果图中我们可以看见,为了营造一种汽车向前跑的效果,在相对位置上我们将其相对事物(树、路灯以及建筑)朝车后移动,也就是向左平移,那么可能有朋友会问车要向前奔跑直接将车向右平移不就行了么,嗯在最初的设计中我也这样考虑过,但是最终实现出来的效果却不尽人意,汽车不断地跑出屏幕又跑进来,效果不连贯而且总感觉怪怪的,因此最终决定汽车静止,相对物体进行平移。

初识化控件咱们就直接忽略掉,来看关键代码

final TranslateAnimation btree = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,
        Animation.RELATIVE_TO_SELF, -1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.0f);


这段代码的意思很简单,树的开始动画,在其起始位置,向左平移相对自身一倍的距离,Animation.RELATIVE_TO_DELF , -1f代表的就是向左平移与自身宽度一倍的距离,因此刚好能够移出屏幕,为什么不用构造方法b,看见这样的效果我想大家也就知道c比b简单得太多太多,效果如图

当然,从左平移出去还不够,为了保持连贯和持续性,咱们还得为其添加一个相应事件,判断其移出屏幕后能够从屏幕右方平移进来并且重复整个动作,代码如下

final TranslateAnimation retree = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1f,
        Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0f);
btree.setAnimationListener(new Animation.AnimationListener() {

    @Override
    public void onAnimationStart(Animation arg0) {
        // TODO Auto-generated method stub
        packeg1.startAnimation(packeg);
        packeg2.startAnimation(packeg);
    }

    @Override
    public void onAnimationRepeat(Animation arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onAnimationEnd(Animation arg0) {
        // TODO Auto-generated method stub
        tree.startAnimation(retree);

    }
});
retree.setAnimationListener(new Animation.AnimationListener() {

    @Override
    public void onAnimationStart(Animation arg0) {
        // TODO Auto-generated method stub
        packeg1.startAnimation(packeg);
        packeg2.startAnimation(packeg);
    }

    @Override
    public void onAnimationRepeat(Animation arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onAnimationEnd(Animation arg0) {
        // TODO Auto-generated method stub
        tree.startAnimation(btree);

    }
});


其实整个项目这里是很关键的地方,也是一个逻辑上比较容易出错的地方,为了将建筑、树木、路灯以及包裹联系起来,什么时候移动,包裹什么时候掉下来,在逻辑上还是需要仔细斟酌的,SDK为我们提供了相应的监听方法也大大减少了我们的工作量。

而最终实现的效果如图:


项目的主要难度在于逻辑上的处理,源码以及资源文件已上传到github:https://github.com/weizainiunai/TranslateAnimation




没有更多推荐了,返回首页