android进阶4step1:Android动画处理与自定义View——动画基础1

文章内容

  • 逐帧动画
  • 视图动画系统
  • 属性动画系统
  • 动画的种类 

分类转:https//blog.csdn.net/pzm1993/article/details/77167049

  • Android的动画可以分为以下3种:

  • 图片动画

图片动画,其实也是逐帧动画,是通过一个接一个的加载绘制对象资源来创建动画,按顺序的播放,像一个胶卷。对于视图动画,他只是单独的图片内容在变换,而不是整个视图。很显然,如果图片过多多大就会导致OOM异常。

  • View动画

视图动画,通多对整个视图不断做图像的变换(平移,缩放,旋转,透明度)产生的动画效果,是一种渐进式动画。

其中观看动画又可以分为:补间动画和逐动动画

  • 属性动画

属性动画,在Android 3.0的(API级别11)引入的,该属性动画系统可以制作动画的任何对象的属性。但是一般来说,属性动画系统是首选的使用方法,因为它更灵活,并提供更多功能。

一,逐帧动画

由多个图像组成的自定义加载动画,每一张图片作为动画的一帧,当顺序执行并给它一定时间间隔展示就形成一种动画的效果

使用AnimationDrawable


定义转:https//www.jianshu.com/p/ce5014c4bc95

的动画一种方法Drawables的英文逐个加载一系列柯林斯绘制资源来创建³³动画。这是一个传统的动画,它是由一系列不同的图像创建的,按照顺序播放,就像一卷电影一样。本。AnimationDrawable类的英文柯林斯绘制动画的基础。

虽然您可以使用AnimationDrawable类API在代码中定义动画的框架,但使用列出组成动画的框架的单个XML文件更简单。这种动画的XML文件属于res/drawable/您的Android项目的目录。在这种情况下,指令的英文动画每帧的顺序状语从句:持续时间

它的实际相当于装绘制的一种容器,来控制绘制的显示 

具体使用:

1,我们准备了三张图片:frame1,2,3来当做这个动画的三帧

2,新建工程,在将图片放到drawable文件夹下,并在drawable文件下(右键new)创建一个drawable资源文件文件

3,(frameanimation.xml)XML由文件一个元素作为根节点状语从句:一系列子节点组成<animation-list><item>

  • 每一个项目对应一帧
  • 持续时间:该帧持续的时间
  • 绘制:该帧对应的图片
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--第一帧-->
    <item android:drawable="@drawable/frame_1" android:duration="100" />
    <!--第二帧-->
    <item android:drawable="@drawable/frame_2" android:duration="100" />
    <!--第三帧-->
    <item android:drawable="@drawable/frame_3" android:duration="100" />
</animation-list>

4,创建视图展示动画activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FrameAnimationActivity">

    <!--将动画视图放在这个view中展示-->
    <View
        android:id="@+id/frame_animation"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:background="@drawable/framanimation" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnStart"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="Start" />

        <Button
            android:id="@+id/btnStop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="Stop" />
        <Button
            android:id="@+id/btnOneShot"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="OneShot" />
    </LinearLayout>

</RelativeLayout>

 5.FrameAnimationActivity.java实现动画效果

重要的三个属性:

  • 开始(); 开启动画
  • 停止();停止动画
  • setOneShot(boolean b);让动画执行一次
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class FrameAnimationActivity extends AppCompatActivity {

    private View mAnimationView;
    private AnimationDrawable animationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化视图
        mAnimationView = findViewById(R.id.frame_animation);
        //拿到视图的背景,也就是之前定义的drawable 强转为AnimationDrawable
        animationDrawable = (AnimationDrawable) mAnimationView.getBackground();
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnStart:
                animationDrawable.start();
                break;
            case R.id.btnStop:
                animationDrawable.stop();
                break;
            case R.id.btnOneShot:
                //默认每一帧都是无限循环的
                //可以通过这个属性设置只执行一轮
                animationDrawable.setOneShot(true);
                break;
        }
    }
}

效果:

二,视图动画系统(View animation)

视图动画的作用对象只能是查看,同在一个图形通过在界面上进行透明度缩放旋转平移的变化。

查看动画的分类:
view动画支持4中动画效果,分别是:

  1. 透明度动画(AlphaAnimation)
  2. 缩放动画(ScaleAnimation)
  3. 平移动画(TranslateAnimation)
  4. 旋转动画(RotateAnimation)
  5. 集合动画(AnimationSet)

不同动画与Java类、xml文件关键字对应关系如下:转:https://www.jianshu.com/p/26a801a755a0

名称Java子类xml关键字说明
透明度动画AlphaAnimation<alpha> 放置在res/anim/目录下透明度渐变
旋转动画RotateAnimation<rotate> 放置在res/anim/目录下视图旋转
缩放动画ScaleAnimation<scale> 放置在res/anim/目录下放大/缩小 视图尺寸大小
平移动画TranslateAnimation<translate> 放置在res/anim/目录下视图位置移动
复合动画AnimationSet<set> 放置在res/anim/目录下一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器

如图所示,图中几个类多是Animation的子类,在java代码中具体实现也是通过这些子类来实现

 

由于Animation是抽象基类,其提供了一些通用的动画属性方法,如下所示

xml属性Java方法说明
android:detachWallpapersetDetachWallpaper(boolean)是否在壁纸上运行
android:durationsetDuration(long)动画的运行时间(以毫秒为单位);必须设置
android:fillAftersetFillAfter(boolean)动画结束时是否保持动画最后的状态;默认为false,优先于fillBefore
android:fillBeforesetFillBefore(boolean)动画结束时是否还原到开始动画前的状态;默认为true
android:fillEnabledsetFillEnabled(boolean)是否应用fillBefore的值,对fillAfter无影响;默认为true
android:interpolatorsetInterpolator(Interpolator)设定插值器(指定的动画效果,譬如回弹等)
android:repeatCountsetRepeatCount(int)重复次数
android:repeatModesetRepeatMode(int)重复类型有两个值,reverse表示倒序回放,restart表示从头播放
android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位为毫秒
android:zAdjustmentsetZAdjustment(int)表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal

这4种动画既能分开独立实现,也可以组合实现复合动画AnimationSet。如果这些动画还是满足不了你,可以自定义动画。不过,后面有了属性动画之后,大部分还是可以满足需求。

view动画的实现可以通过Xml来定义,也可以通过java代码来动态设置。对于view动画,建议使用XML来定义动画,可读性好,而且能过复用。而对于属性动画,则建议是通过代码动态设置,后文会介绍。

 

一、透明度动画(AlphaAnimation)

控制视图的透明度

透明度动画(Alpha)-- 属性

xml属性Java方法说明
android:fromAlphaAlphaAnimation(float fromAlpha, …)动画开始的透明度(0.0到1.0,0.0是全透明1.0是不透明
android:toAlphaAlphaAnimation(…, float toAlpha)动画结束的透明度,同上

 步骤:

1、在res目录下创建anim文件夹 新建一个xml文件  使用<alpha> 标签这里命名为:alpha_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<!--放在set动画集合中-->
<set  android:duration="1000" xmlns:android="http://schemas.android.com/apk/res/android">
    <!--fromAlpha 开始的透明度 0.0->1.0 从全透明到不透明 1.0代表完全不透明-->
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.1" />
</set>

2、创建显示动画的布局 这里以TextView为这个视图 这里是:viewanimation.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_alpha"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:padding="20dp"
            android:onClick="onClick"
            android:text="alpha"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            android:textColor="#ffffff"
            android:textSize="30sp" />

    </LinearLayout>

</ScrollView>

 3.java代码实现  实现点击textView 透明度发生变化的效果


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.demo.android4step1.R;

/**
 * <p>文件描述:<p>
 * <p>作者:Mr-Donkey<p>
 * <p>创建时间:2018/12/9 16:40<p>
 * <p>更改时间:2018/12/9 16:40<p>
 * <p>版本号:1<p>
 */
public class AlphaAnimationActivity extends AppCompatActivity {

    private Animation animation;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewanimation);
    }


    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_alpha:
                //加载动画拿到 animation对象
                animation = AnimationUtils.loadAnimation(this, R.anim.alpha_animation);
                //通过此时的view设置动画
                view.startAnimation(animation);
                break;
        }
    }
}

效果:

二、缩放动画(ScaleAnimation)


控制每一个视图的X、Y轴的缩放程度

缩放动画(Scale)-- 属性 

xml属性Java方法说明
android:fromXScaleScaleAnimation(float fromX, …)初始X轴缩放比例,1.0表示无变化
android:toXScaleScaleAnimation(…, float toX, …)结束X轴缩放比例
android:fromYScaleScaleAnimation(…, float fromY, …)初始Y轴缩放比例
android:toYScaleScaleAnimation(…, float toY, …)结束Y轴缩放比例
android:pivotXScaleAnimation(…, float pivotX, …)基准点)缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角以父控件宽度的50%做为初始点)
android:pivotYScaleAnimation(…, float pivotY)基准点)缩放起点Y轴坐标,同上规律

实现步骤:

1、在上面anim文件夹中新建xml文件 使用<scale>标签 这里命名为:

<?xml version="1.0" encoding="utf-8"?>
   <!--duration:动画间隔 fillAfter:保持最后的状态,不恢复原来的状态 -->
<set  xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="true"
>
   <!--X轴初始值from为原来的宽度,结束后to变成原来的2倍宽度-->
   <!--Y轴不变-->
    <scale
        android:fromXScale="1.0"
        android:toXScale="2.0"
        android:fromYScale="1.0"
        android:toYScale="1.0">
    </scale>
</set>

2、在上面的布局viewanimation.xml中

将textView的部分属性抽取出来(如果有多个view共用的话,抽取style)

进入布局文件 点击Refactor——>Extract——>Style

提取共用的部分作为style,方便以后的视图使用,就不用重复写这么多次了

此时textView就可以用一个style 包含之前的属性

     <TextView
            android:id="@+id/tv_alpha"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="alpha"
            style="@style/AnimationTextView" />

然后再添加一个 TextView  在alpha的下面

   <!--这是Scale动画的视图-->
        <TextView
            android:id="@+id/tv_scale"
            style="@style/AnimationTextView"
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="scale" />

3.java 代码实现 在OnClick函数添加

   case R.id.tv_scale:
                //加载动画拿到 animation对象
                animation = AnimationUtils.loadAnimation(this, R.anim.scale_animation);
                view.startAnimation(animation);
                break;

效果:

sacle的基准点属性

android:pivotXScaleAnimation(…, float pivotX, …)基准点)缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:pivotYScaleAnimation(…, float pivotY)基准点)缩放起点Y轴坐标,同上规律

修改一下上面代码:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true"
    >
   <!--X轴初始值from为原来的宽度,结束后to变成原来的2倍宽度-->
   <!--Y轴也一样-->
    <scale
        android:fromXScale="1.0"
        android:toXScale="2.0"
        android:fromYScale="1.0"
        android:toYScale="2.0"
        android:pivotX="50%"
        android:pivotY="50%">
    </scale>
</set>

让视图居中 

     <!--这是Scale动画的视图-->
        <TextView
            android:id="@+id/tv_scale"
            style="@style/AnimationTextView"
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:layout_gravity="center_horizontal"
            android:text="scale" />

 效果:以视图的X、Y周轴中心作为基准点,放大两被的效果

三、平移动画(TranslateAnimation)


平移动画(Translate)-- 属性

xml属性Java方法说明
android:fromXDeltaTranslateAnimation(float fromXDelta, …)起始点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:fromYDeltaTranslateAnimation(…, float fromYDelta, …)起始点Y轴从标,同上规律
android:toXDeltaTranslateAnimation(…, float toXDelta, …)结束点X轴坐标,同上规律
android:toYDeltaTranslateAnimation(…, float toYDelta)结束点Y轴坐标,同上规律

步骤:

1、anim文件夹中创建 xml文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true"
    >
    <!--fromXDelta 开始X轴的偏移 toXDelta 目的地的偏移 50% 为控件的宽度的50%-->
   <!--Y轴同理-->
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="50%"
        android:toYDelta="0">
        
    </translate>
</set>

2、给布局中添加视图(省略了)

3、java代码的实现

      case R.id.tv_translate:
                //加载动画拿到 animation对象
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_animation);
                view.startAnimation(animation);
                break;

效果:

android:repeatCountsetRepeatCount(int)重复次数
android:repeatModesetRepeatMode(int)重复类型有两个值,reverse表示倒序回放,restart表示从头播放

两种重复模式 :restart 重头开始  reverse 原路返回

1、重头开始 restart

   android:repeatMode="restart"
   android:repeatCount="1"

2、原路返回 reverse

四、旋转动画(RotateAnimation)


旋转动画(Rotate)-- 属性

xml属性Java方法说明
android:fromDegreesRotateAnimation(float fromDegrees, …)旋转开始角度,正代表顺时针度数,负代表逆时针度数
android:toDegreesRotateAnimation(…, float toDegrees, …)旋转结束角度,正代表顺时针度数,负代表逆时针度数
android:pivotXRotateAnimation(…, float pivotX, …)缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:pivotYRotateAnimation(…, float pivotY)

缩放起点Y坐标,同上规律

步骤:同理 anim文件夹中创建xml文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true"
    >
    <!--开始角度为0 即正常的样子  结束角度
    90度 则发生偏转90 正数顺时针 负数逆时针-->
    <rotate
        android:fromDegrees="0"
        android:toDegrees="90">
    </rotate>

</set>

 布局添加一个视图作为旋转动画的视图

       <!--这是rotate动画的视图-->
        <TextView
            android:id="@+id/tv_rotate"
            style="@style/AnimationTextView"
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:gravity="center"
            android:layout_gravity="center_horizontal"
            android:text="rotate" />
        <!--如果视图显示不全 可以再下方加一个空白的View-->
        <View
            android:layout_width="match_parent"
            android:layout_height="300dp"/>

3.java代码中添加一个点击事件

       case R.id.tv_rotate:
                //加载动画拿到 animation对象
                animation = AnimationUtils.loadAnimation(this, R.anim.rotate_animation);
                view.startAnimation(animation);
                break;

效果:   如果需要改基准点可以设置 pivot 属性

五、集合动画(AnimationSet)

一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器

将上述四种动画结合起来显示

例子1:anim文件夹中创建 set.xml 包含旋转和平移动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--旋转动画-->
    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="720" />
    <!--位移动画-->
    <translate
        android:duration="1000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="500"
        android:toYDelta="0" />

</set>

2.添加视图(略)

3.添加点击事件(略)

效果

android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位为毫秒

startOffset 函数可以这是等待多少时间之后再运行当前这个动画 

拿上面的例子,让它先旋转完成再进行平移

   <!--位移动画-->
    <translate
        android:duration="1000"
        android:startOffset="1000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="500"
        android:toYDelta="0" />

效果:

Animation还有如下一些比较实用的方法介绍:

Animation类的方法解释
reset()重置Animation的初始化
cancel()取消Animation动画
start()开始Animation动画
hasStarted()判断当前Animation是否开始
hasEnded()判断当前Animation是否结束

既然补间动画只能给View使用,那就来看看View中和动画相关的几个常用方法吧,如下:

View类的常用动画操作方法解释
startAnimation(Animation animation)对当前View开始设置的Animation动画
clearAnimation()取消当View在执行的Animation动画

特别特别注意视图动画执行之后并未改变View的真实布局属性值。切记这一点,譬如我们在Activity中有一个Button在屏幕上方,我们设置了平移动画移动到屏幕下方然后保持动画最后执行状态呆在屏幕下方,这时如果点击屏幕下方动画执行之后的Button是没有任何反应的,而点击原来屏幕上方没有Button的地方却响应的是点击Button的事件。

动画监听

  • 动画监听器接收来自动画的通知。通知表示与动画相关的事件,例如动画的结束或重复
  • 使用方法:
Animation.addListener(new AnimatorListener() {
          @Override
          public void onAnimationStart(Animation animation) {
              //动画开始时执行
          }
      
           @Override
          public void onAnimationRepeat(Animation animation) {
              //动画重复时执行
          }

         @Override
          public void onAnimationCancel()(Animation animation) {
              //动画取消时执行
          }
    
          @Override
          public void onAnimationEnd(Animation animation) {
              //动画结束时执行
          }
      });
  • 视图动画的监听只能通过此方式,且必须要复写全部4个方法。
  • 属性动画时,可以采用Animator.addListener(new AnimatorListenerAdapter(){ //复写指定方法 })------动画适配器AnimatorListenerAdapter中已经实现好每个接口

视图动画-插值器(Interpolator)


插值器是在XML中定义的一个动画修改器,它影响动画的变化率。这允许现有动画附加加速、减速、重复、反弹等效果。

 继承关系

系统为我们提供了上图中的各种插值器,其都是实现了Interpolator接口的实现类,具体说明如下:

java类XML 资源ID说明
AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator先加速再减速
AccelerateInterpolator@android:anim/accelerate_interpolator持续加速
AnticipateInterpolator@android:anim/anticipate_interpolator先退后再加速前进
AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator先退后再加速前进,超出终点后再回终点
BounceInterpolator@android:anim/bounce_interpolator结束时弹球效果
CycleInterpolator@android:anim/cycle_interpolator周期运动
DecelerateInterpolator@android:anim/decelerate_interpolator减速
LinearInterpolator@android:anim/linear_interpolator匀速
OvershootInterpolator@android:anim/overshoot_interpolator向前弹出一定值之后回到原来位置(快速完成动画,超出再回到结束样式)

使用方法

  • XML方式
<set android:interpolator="@android:anim/accelerate_interpolator">
    ...
</set>
  • JAVA方式  使用不同的速率 直接new上面给出的类就行了 android定义好的
                //加载动画拿到 animation对象
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_animation);
                //创建插值器对象
                Interpolator interpolator = new OvershootInterpolator();
                //为动画添加插值器
                view.setInterpolator(interpolator);
                view.startAnimation(animation);
             

给动画多添加了一个插值器

自定义插值器

某些情景可能你会发现系统提供的插值器不能满足需求,此时我们需要自定义插值器。有两种实现方式:

XML自定义实现JAVA代码实现方式

XML实现

  1. res/anim/下创建filename.xml
  2. 修改插值器属性(如下不作任何修改,则与系统预设插值器功能相同)
<?xml version="1.0" encoding="utf-8"?>
<InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
    android:attribute_name="value"
    />
  1. 视图动画中引用该文件(资源引用为@[package:]anim/filename

XML实现方式本质就是修改系统提供的插值器的某些属性,具体可修改属性如下:

插值器可修改属性属性说明
<accelerateDecelerateInterpolator>无属性 
<accelerateInterpolator>android:factorFloat,加速速率(默认值为1)
<anticipateInterpolator>android:tensionFloat. 起始点后拉的张力数(默认值为2)
<anticipateOvershootInterpolator>android:tension
android:extraTension
Float. 起始点后拉的张力数(默认值为2)
Float. 拉力的倍数(默认值为1.5)
<bounceInterpolator>无属性 
<cycleInterpolator>android:cyclesInteger. 循环次数(默认为1)
<decelerateInterpolator>android:factorFloat. 减速的速率(默认为1)
<linearInterpolator>无属性 
<overshootInterpolator>android:tensionFloat. 超出终点后的张力(默认为2)

JAVA方式

在此只讨论原理,不设计具体逻辑(奈何我是个数学渣,公式真的是一头雾水= =)

在前面继承关系的图中,我们可以看出所有插值器继承自BaseInterpolator,其又实现了Interpolator接口,而Interpolator接口继承自TimeInterpolator接口,TimeInterpolator接口中的唯一抽象方法为getInterpolation(float input),这个方法是由系统调用的,其中的参数input代表动画的时间,在0和1之间,也就是开始和结束之间。

我们可以看一下系统提供的插值器,如AccelerateDecelerateInterpolator,其源码极其极其简单,如下:

@HasNativeInterpolator
public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }
}

可以看到,核心方法就是前面提到的getInterpolation(),其效果就是通过这一数学公式得来的,好久不看数学,已经快看不懂这个公式结果是什么了,汗颜= =

public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

由此我们总结以下JAVA方式自定义插值器:

  • 根据需求实现TimeInterpolator接口
  • 实现抽象方法getInterpolation(),在该方法中处理逻辑
  • 为动画设置该自定义插值器处。

属性动画的链接:转 Android的进阶4step1:动画基础2之属性动画(Property Animation)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值