精华内容
下载资源
问答
  • Android缩放动画

    千次阅读 2015-07-27 14:20:20
    Android缩放动画核心方法public void startAnimation(Animation animation)执行动画,参数可以是各种动画的对象,Animation的多态,也可以是组合动画,后面会有。 4个参数构造方法/** * Constructor to use when ...

    Android缩放动画

    核心方法

    public void startAnimation(Animation animation)
    • 执行动画,参数可以是各种动画的对象,Animation的多态,也可以是组合动画,后面会有。

    4个参数构造方法

    /**
     * Constructor to use when building a ScaleAnimation from code
     * 
     * @param fromX Horizontal scaling factor to apply at the start of the animation
     * @param toX Horizontal scaling factor to apply at the end of the animation
     * @param fromY Vertical scaling factor to apply at the start of the animation
     * @param toY Vertical scaling factor to apply at the end of the animation
     */
    public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
        mResources = null;
        mFromX = fromX;
        mToX = toX;
        mFromY = fromY;
        mToY = toY;
        mPivotX = 0;
        mPivotY = 0;
    }

    用法

    public void scale(View view) {
        // 创建缩放的动画对象
        ScaleAnimation sa = new ScaleAnimation(0f,1.0f,0f,1.0f);
        // 设置动画播放的时间
        sa.setDuration(1000);
        // 开始播放动画
        iv.startAnimation(sa);
    }

    效果

    以图片左上角为原点,从没有,放大到图片原大小


    6个参数构造方法

       /**
        * Constructor to use when building a ScaleAnimation from code
        * 
        * @param fromX Horizontal scaling factor to apply at the start of the animation
        * @param toX Horizontal scaling factor to apply at the end of the animation
        * @param fromY Vertical scaling factor to apply at the start of the animation
        * @param toY Vertical scaling factor to apply at the end of the animation
        * @param pivotX The X coordinate of the point about which the object is being scaled, specified as an absolute number where 0 is the left edge. (This point remains fixed while the object changes size.)
        * @param pivotY The Y coordinate of the point about which the object is being scaled, specified as an absolute number where 0 is the top edge. (This point remains fixed while the object changes size.)
        */
       public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) {
           mResources = null;
           mFromX = fromX;
           mToX = toX;
           mFromY = fromY;
           mToY = toY;
    
           mPivotXType = ABSOLUTE;
           mPivotYType = ABSOLUTE;
           mPivotXValue = pivotX;
           mPivotYValue = pivotY;
           initializePivotPoint();
       }
    • 前4个参数和上面的用法一样,后两个参数是设置图片缩放的原点,四个参数的构造默认将这两个参数都设置了0,所以是在图片左上角开始缩放

    用法

    ScaleAnimation sa = new ScaleAnimation(0f, 1.0f, 0f, 1.0f, iv.getWidth() / 2, iv.getHeight() / 2);
    // 设置动画播放的时间
    sa.setDuration(1000);
    // 开始播放动画
    iv.startAnimation(sa);

    效果

    以图片的中心为原点,从没有放大到图片原大小


    8个参数构造方法

      /**
        * Constructor to use when building a ScaleAnimation from code
        * 
        * @param fromX Horizontal scaling factor to apply at the start of the animation
        * @param toX Horizontal scaling factor to apply at the end of the animation
        * @param fromY Vertical scaling factor to apply at the start of the animation
        * @param toY Vertical scaling factor to apply at the end of the animation
        * @param pivotXType Specifies how pivotXValue should be interpreted. One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.
        * @param pivotXValue The X coordinate of the point about which the object is being scaled, specified as an absolute number where 0 is the left edge. (This point remains fixed while the object changes size.) This value can either be an absolute number if pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
        * @param pivotYType Specifies how pivotYValue should be interpreted. One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT.
        * @param pivotYValue The Y coordinate of the point about which the object is being scaled, specified as an absolute number where 0 is the top edge. (This point remains fixed while the object changes size.) This value can either be an absolute number if pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
        */
       public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
           mResources = null;
           mFromX = fromX;
           mToX = toX;
           mFromY = fromY;
           mToY = toY;
    
           mPivotXValue = pivotXValue;
           mPivotXType = pivotXType;
           mPivotYValue = pivotYValue;
           mPivotYType = pivotYType;
           initializePivotPoint();
       }

    用法

    // 创建缩放的动画对象
    ScaleAnimation sa = new ScaleAnimation(0f, 1.0f, 0f, 1.0f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
    // 设置动画播放的时间
    sa.setDuration(1000);
    // 开始播放动画
    iv.startAnimation(sa);
    • 和上面6个参数的相比只是多了第5和第7个参数,分别设置他们的类型,注释里面已经说明了,可以设置Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT类型

    效果

    效果和上面一样,以图片的中心为原点,从没有放大到图片原大小。


    设置动画重复播放的次数的方法

    /**
     * Sets how many times the animation should be repeated. If the repeat
     * count is 0, the animation is never repeated. If the repeat count is
     * greater than 0 or {@link #INFINITE}, the repeat mode will be taken
     * into account. The repeat count is 0 by default.
     *
     * @param repeatCount the number of times the animation should be repeated
     * @attr ref android.R.styleable#Animation_repeatCount
     */
    public void setRepeatCount(int repeatCount) {
        if (repeatCount < 0) {
            repeatCount = INFINITE;
        }
        mRepeatCount = repeatCount;
    }

    使用

    sa.setRepeatCount(2);

    设置动画重复播放的模式的方法

    /**
     * Defines what this animation should do when it reaches the end. This
     * setting is applied only when the repeat count is either greater than
     * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}. 
     *
     * @param repeatMode {@link #RESTART} or {@link #REVERSE}
     * @attr ref android.R.styleable#Animation_repeatMode
     */
    public void setRepeatMode(int repeatMode) {
        mRepeatMode = repeatMode;
    }

    使用

    sa.setRepeatMode(ScaleAnimation.REVERSE);
    展开全文
  • android 垂直缩放动画效果
  • Android 安卓动画 补间动画 - 缩放动画

    千次阅读 多人点赞 2018-08-31 19:36:54
    补间动画之缩放动画 实现效果:点击按钮后实现按钮放大效果 补间动画概念:就是从一个画面过渡到另一个画面时让人看到中间动画效果! 动画 - 相关文章篇 帧动画 帧动画: ...

    补间动画之缩放动画

    实现效果:点击按钮后实现按钮放大效果

    补间动画概念:就是从一个画面过渡到另一个画面时让人看到中间动画效果!


    动画 - 相关文章篇

    帧动画

    帧动画:  https://blog.csdn.net/qq_40881680/article/details/82222684

     

    补间动画

    补间动画-平移动画:  https://blog.csdn.net/qq_40881680/article/details/82255459

    补间动画-缩放动画:  https://blog.csdn.net/qq_40881680/article/details/82260914

    补间动画-旋转动画:  https://blog.csdn.net/qq_40881680/article/details/82261557

    补间动画-透明/渐变动画:  https://blog.csdn.net/qq_40881680/article/details/82261869

    补间动画-组合动画(四个动画一起播放):  https://blog.csdn.net/qq_40881680/article/details/82285987

     

    属性动画

    属性动画-渐变透明动画:  https://blog.csdn.net/qq_40881680/article/details/82318363

    属性动画-旋转动画:  https://blog.csdn.net/qq_40881680/article/details/82354017

    属性动画-缩放动画:  https://blog.csdn.net/qq_40881680/article/details/82377850

    属性动画-移动动画:  https://blog.csdn.net/qq_40881680/article/details/82378391

    属性动画-组合动画:  https://blog.csdn.net/qq_40881680/article/details/82381258


    效果图 篇


    操作步骤 篇

    res下创建anim文件夹,右击res文件夹,按下图操作创建

     

    找到anim点击OK,此时就创建好了

     

    在这个文件夹(anim)下新建xml文件,右击anim文件夹按下图操作创建

     

    在这个xml文件中写入属性,属性详细见下列表格解释:

    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fillAfter="false"
        android:fillBefore="true"
        android:fillEnabled="true"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="0"
        android:repeatMode="restart"
        android:startOffset="0"
        android:toXScale="2.5"
        android:toYScale="2.5">
    
    </scale>

     

    属性 详细解释
    android:duration="2000" 动画持续时间。即这个动画会持续多长时间,单位(ms)
    android:fillAfter="false" 动画播放完毕后,是否会停止在动画结束的状态,优先存在于fillBefore
    android:fillBefore="true" 动画播放完毕后,是否会恢复原始状态
    android:fillEnabled="true" 是否应用与fillBefore的值,默认:true
    android:fromXScale="1" X轴起始缩放倍数
    android:fromYScale="1" Y轴起始缩放倍数
    android:pivotX="50%" 缩放轴点X坐标
    android:pivotY="50%" 缩放轴点Y坐标
    android:repeatCount="0" 重复次数,值infinite为无限一直重复
    android:repeatMode="restart" 播放的动画模式restart表示正序播放,reverse代表倒序播放,默认是restart
    android:startOffset="0" 动画延迟开始时间(多长时间后开始执行动画)
    android:toXScale="2.5" 缩放轴点的X坐标
    android:toYScale="2.5" 缩放轴点的Y坐标

    布局文件 篇

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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"
        tools:context=".MainActivity">
    
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="150dp"
            android:text="这是缩放效果动画" />
    
    </LinearLayout>

    代码逻辑 篇

    缩放动画用到Animation,如下操作,就可以实现,点击按钮后放大效果

    package com.example.text.donghua;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Button button;
        Animation animation;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
    
            }
    
        private void initView() {
            button = (Button) findViewById(R.id.button);
            animation = AnimationUtils.loadAnimation(this,R.anim.start);
            button.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.button:
                    button.startAnimation(animation);
                    break;
            }
        }
    }
    

    最终效果图:

    展开全文
  • 来源丨安卓模拟器https://mp.weixin.qq.com/s/N90-6IHDbnFgddqWMxyvQw1.Evaluator自定义1)Evaluator介绍上一节中的8.4.3 Android动画合集之属性动画-初见,使用动画的第一步都是:调用ValueAnimator的ofInt(),of...

    efafe138e3e677cb6fd54329a8131089.png

    来源丨安卓模拟器https://mp.weixin.qq.com/s/N90-6IHDbnFgddqWMxyvQw

    1.Evaluator自定义

    1)Evaluator介绍

    上一节中的8.4.3 Android动画合集之属性动画-初见,使用动画的第一步都是:

    调用ValueAnimator的ofInt(),ofFloat()或ofObject()静态方法创建ValueAnimator实例!

    在例子中,ofInt和ofFloat我们都用到了,分别用于对浮点型和整型的数据进行动画操作!

    那么ofObject()?初始对象和结束对象?如何过渡法?或者说这玩意怎么用?

    好的,带着疑问,我们先来了解一个东西:Evaluator,在属性动画概念叨叨逼处其实我们就说到了这个东西:

    3d37ee7bdb22d527c2984794853b76ac.png

    用来告诉动画系统如何从初始值过渡到结束值好的,我们的入手点没错! 我们进去IntEvaluator的源码,看下里面写了些什么?

    296f8a0f48488d8cbb46f30c6d36a1a1.png

    嗯,实现了TypeEvaluator接口,然后重写了evaluate()方法,参数有三个,依次是:

    • fraction动画的完成度,我们根据他来计算动画的值应该是多少

    • startValue动画的起始值

    • endValue动画的结束值

    动画的值 = 初始值 + 完成度 * (结束值 - 初始值)

    同样的还有FloatEvaluator,我们想告诉系统如何从初始对象过度到结束对象,那么我们就要 自己来实现TypeEvaluator接口,即自定义Evaluator了,说多无益,写个例子来看看:

    2)使用示例

    运行效果图

    37d81f1c92c1ef2068532f788c6e4a31.gif

    代码实现

    定义一个对象Point.java,对象中只有x,y两个属性以及get,set方法~

    /** * Created by Jay on 2015/11/18 0018. */publicclassPoint{ privatefloat x; privatefloat y; publicPoint(){ } publicPoint(float x,float y){this.x = x;this.y = y; }publicfloat getX(){return x; }publicfloat getY(){return y; }publicvoid setX(float x){this.x = x; }publicvoid setY(float y){this.y = y; }}

    接着自定义Evaluator类:PointEvaluator.java,实现接口重写evaluate方法~

    /** * Created by Jay on 2015/11/18 0018. */public class PointEvaluator implements TypeEvaluator<Point>{    @Override    publicPoint evaluate(float fraction,Point startValue,Point endValue){float x = startValue.getX()+ fraction *(endValue.getX()- startValue.getX());float y = startValue.getY()+ fraction *(endValue.getY()- startValue.getY());        Point point =newPoint(x, y);return point;    }}

    然后自定义一个View类:AnimView.java,很简单~

    /** * Created by Jay on 2015/11/18 0018. */public class AnimView extends View {public static final float RADIUS = 80.0f;private Point currentPoint;private Paint mPaint;public AnimView(Context context) {this(context, null); }public AnimView(Context context, AttributeSet attrs) {super(context, attrs); init(); }public AnimView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr); }private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.BLUE); }private void drawCircle(Canvas canvas){float x = currentPoint.getX();float y = currentPoint.getY(); canvas.drawCircle(x, y, RADIUS, mPaint); }private void startAnimation() { Point startPoint = new Point(RADIUS, RADIUS); Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS); ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) { currentPoint = (Point) animation.getAnimatedValue(); invalidate(); } }); anim.setDuration(3000l); anim.start(); }@Overrideprotected void onDraw(Canvas canvas) {if (currentPoint == null) { currentPoint = new Point(RADIUS, RADIUS); drawCircle(canvas); startAnimation(); } else { drawCircle(canvas); } }}

    最后MainActivity.java处实例化这个View即可~

    public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(new AnimView(this)); }}

    3)示例增强版

    我们上面示例的基础上加上圆移动时的颜色变化~ 这里我们另外用一个ObjectAnimator来加载颜色变化的动画,我们在View中加多个 int color来控制颜色,另外写上getColor()和setColor()的方法,我们先来自定义个Evaluator吧~

    运行效果图

    11888cfbf2e40617181958edbd333efa.gif

    实现代码

    ColorEvaluator.java

    /** * Created by Jay on 2015/11/18 0018. */public class ColorEvaluator implements TypeEvaluator<Integer>{@Overridepublic Integer evaluate(float fraction, Integer startValue, Integer endValue) {int alpha = (int) (Color.alpha(startValue) + fraction *                (Color.alpha(endValue) - Color.alpha(startValue)));int red = (int) (Color.red(startValue) + fraction *                (Color.red(endValue) - Color.red(startValue)));int green = (int) (Color.green(startValue) + fraction *                (Color.green(endValue) - Color.green(startValue)));int blue = (int) (Color.blue(startValue) + fraction *                (Color.blue(endValue) - Color.blue(startValue)));return Color.argb(alpha, red, green, blue);    }}

    然后自定义View那里加个color,get和set方法;创建一个ObjectAnimator, 和AnimatorSet,接着把动画组合到一起就到,这里就加点东西而已,怕读者有问题, 直接另外建个View吧~

    AnimView2.java

    /** * Created by Jay on 2015/11/18 0018. */public class AnimView2 extends View {public static final float RADIUS = 80.0f;private Point currentPoint;private Paint mPaint;private int mColor;public AnimView2(Context context) {this(context, null); }public AnimView2(Context context, AttributeSet attrs) {super(context, attrs); init(); }public AnimView2(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr); }private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.BLUE); }private void drawCircle(Canvas canvas){float x = currentPoint.getX();float y = currentPoint.getY(); canvas.drawCircle(x, y, RADIUS, mPaint); }private void startAnimation() { Point startPoint = new Point(RADIUS, RADIUS); Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS); ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) { currentPoint = (Point) animation.getAnimatedValue(); invalidate(); } }); ObjectAnimator objectAnimator = ObjectAnimator.ofObject(this, "color", new ColorEvaluator(), Color.BLUE, Color.RED);//动画集合将前面两个动画加到一起,with同时播放 AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(anim).with(objectAnimator); animatorSet.setStartDelay(1000l); animatorSet.setDuration(3000l); animatorSet.start(); }@Overrideprotected void onDraw(Canvas canvas) {if (currentPoint == null) { currentPoint = new Point(RADIUS, RADIUS); drawCircle(canvas); startAnimation(); } else { drawCircle(canvas); } }//color的get和set方法~public int getColor() {return mColor; }public void setColor(int color) { mColor = color; mPaint.setColor(color); invalidate(); }}

    然后MainActivity,setContentView那里把AnimView改成AnimView2就好~

    2.Interpolator(补间器)

    嗯,在讲补间动画的时候我们就讲过这个东东了~不知道你还有印象没?

    a16c83506c5e8dc372538ebd806c7153.png

    上面的补间器补间动画和属性动画都可用,而且补间动画还新增了一个TimeInterpolator接口 该接口是用于兼容之前的Interpolator的,这使得所有过去的Interpolator实现类都可以直接拿过来 放到属性动画当中使用!我们可以调用动画对象的setInterpolator()方法设置不同的Interpolator! 我们先该点东西,让小球从屏幕正中央的顶部掉落到底部~ 然后我们会我们为我们的集合动画调用下述语句: animatorSet.setInterpolator(new AccelerateInterpolator(2f)); 括号里的值用于控制加速度~

    运行效果

    fa872be9bef895efd70b7b877ff75c84.gif

    好像有点不和常理,正常应该是会弹起来的吧,我们换成BounceInterpolator试试~

    545ba57e8dd41219a8a0e72a1153303f.gif

    嘿嘿,效果蛮赞的,当然还有N多个系统提供好的Interpolator,大家可以自己一一尝试,这里就 不慢慢跟大家纠结了~

    下面我们来看看:

    1)Interpolator的内部实现机制

    我们先到TimeInterpolator接口的源码,发现这里只有一个getInterpolation()方法;

    1804a3e34dac99816dda88db1f4556b6.png

    简单的解释 getInterpolation()方法中接收一个input参数,这个参数的值会随着动画的运行而不断变化, 不过它的变化是非常有规律的,就是根据设定的动画时长匀速增加,变化范围是0到1。 也就是说当动画一开始的时候input的值是0,到动画结束的时候input的值是1,而中间的值则 是随着动画运行的时长在0到1之间变化的。

    这里的input值决定了我们TypeEvaluator接口里的fraction的值。 input的值是由系统经过计算后传入到getInterpolation()方法中的,然后我们可以自己实现 getInterpolation()方法中的算法,根据input的值来计算出一个返回值,而这个返回值就是fraction了。

    我们可以看看LinearInterpolator里的代码:

    a22d36a7162603e5b0a74139688af64b.png

    这里没有处理过直接返回input值,即fraction的值就是等于input的值,这就是匀速运动的 Interpolator的实现方式!其实无非就是算法不同,这就涉及到一些数学的东西了,又一次 体会到数学的重要性了,这里再贴个BounceInterpolator的源码吧:

    37e747a69e455d91b2a4744b4f59495e.png

    别问我这里的算法,我也不知道哈,我们再找个容易理解点的:AccelerateDecelerateInterpolator

    89cf321ecd3ab2ca1de74703f57109b4.png

    这个Interpolator是先加速后减速效果的: (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f 的算法理解:

    解:由input的取值范围为[0,1],可以得出cos中的值的取值范围为[π,2π],对应的值为-1和1; 再用这个值来除以2加上0.5之后,getInterpolation()方法最终返回的结果值范围还是[0,1], 对应的曲线图如下:

    fd2d8abc6f8315a61f8c0ddcf37b1051.png

    所以是一个先加速后减速的过程!

    嗯,学渣没法玩了...72df6a58e65dc7ffe4ee948e499f227c.gif,上面全是郭大叔文章里搬过来的...我想静静...

    2)自定义Interpolator

    好吧,还是等会儿再忧伤吧,写个自定义的Interpolator示例先: 非常简单,实现TimeInterpolator接口,重写getInterpolation方法

    示例代码如下

    private class DecelerateAccelerateInterpolator implements TimeInterpolator {@Overridepublic float getInterpolation(float input) {if (input < 0.5) {return (float) (Math.sin(input * Math.PI) / 2); } else {return 1 - (float) (Math.sin(input * Math.PI) / 2); } }}

    调用setInterpolator(new DecelerateAccelerateInterpolator())设置下即可~ 限于篇幅就不贴图了~

    3.ViewPropertyAnimator

    3.1后系统当中附增的一个新的功能,为View的动画操作提供一种更加便捷的用法! 假如是以前,让一个TextView从正常状态变成透明状态,会这样写:

    ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 0f);  animator.start();

    而使用ViewPropertyAnimator来实现同样的效果则显得更加易懂:

    textview.animate().alpha(0f); 

    还支持连缀用法,组合多个动画,设定时长,设置Interpolator等~

    textview.animate().x(500).y(500).setDuration(5000) .setInterpolator(new BounceInterpolator());

    用法很简单,使用的时候查下文档就好~,另外下面有几个细节的地方要注意一下!

    整个ViewPropertyAnimator的功能都是建立在View类新增的animate()方法之上的, 这个方法会创建并返回一个ViewPropertyAnimator的实例,之后的调用的所有方法, 设置的所有属性都是通过这个实例完成的。

    使用ViewPropertyAnimator将动画定义完成之后,动画就会自动启动 并且这个机制对于组合动画也同样有效,只要我们不断地连缀新的方法, 那么动画就不会立刻执行,等到所有在ViewPropertyAnimator上设置的方法都执行完毕后, 动画就会自动启动。当然如果不想使用这一默认机制的话,我们也可以显式地调用 start()方法来启动动画。

    ViewPropertyAnimator的所有接口都是使用连缀的语法来设计的,每个方法的返回值都是 它自身的实例,因此调用完一个方法之后可以直接连缀调用它的另一个方法,这样把所有的 功能都串接起来,我们甚至可以仅通过一行代码就完成任意复杂度的动画功能。

    efafe138e3e677cb6fd54329a8131089.png

    展开全文
  • 一、ValueAnimatorValueAnimator是值的变动,可以控制控件的一些值,从而达到变化动画的效果。 public void doAnimation() {// final ValueAnimator valueAnimatorInt = ValueAnimator.ofInt(0,400,100,555,250); //...

    一、ValueAnimator

    ValueAnimator是值的变动,可以控制控件的一些值,从而达到变化动画的效果。

        public void doAnimation() {//        final ValueAnimator valueAnimatorInt = ValueAnimator.ofInt(0,400,100,555,250);        //输入需要变化的值,是个变化的数组,可以有int类型和float类型        final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f,400.0f,100.0f,555.0f,250.0f);        valueAnimator.setDuration(9000);//动画持续时间        //监听动画的变化时间,在变化中对控件进行操作,也可以通过handle来做一些有趣的事情        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //获得变化的值                Float curValueFloat = (Float) valueAnimator.getAnimatedValue();                //设置为整型                int curValue = curValueFloat.intValue();                //改变控件的位置,layout对应的是控件的位置                valueTV.layout(curValue, curValue, curValue + imageView.getWidth(), curValue + imageView.getHeight());            }        });        valueAnimator.start();    }

    监听器三个

    4b251ecb4fc72da1852ad7def752bf03.png
            //监听1        valueAnimator.addPauseListener(new Animator.AnimatorPauseListener() {            @Override            public void onAnimationPause(Animator animation) {                //暂停            }            @Override            public void onAnimationResume(Animator animation) {                //运行            }        });        //监听2        valueAnimator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                //开始            }            @Override            public void onAnimationEnd(Animator animation) {                //结束            }            @Override            public void onAnimationCancel(Animator animation) {                //取消            }            @Override            public void onAnimationRepeat(Animator animation) {                //循环一次            }        });        //监听3        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //数值更新            }        });

    移除监听器 当移除监听器时,正在执行的动画不会受到影响,但是之后再执行动画,动画的监听效果将不会再呈现。

    /**  * 移除AnimatorUpdateListener  */  void removeUpdateListener(AnimatorUpdateListener listener);  void removeAllUpdateListeners();   /**   * 移除AnimatorListener   */  void removeListener(AnimatorListener listener);  void removeAllListeners();

    不常用函数

    /** * 延时多久时间开始,单位是毫秒 */public void setStartDelay(long startDelay)/** * 完全克隆一个ValueAnimator实例,包括它所有的设置以及所有对监听器代码的处理 */public ValueAnimator clone()

    常用函数

    /** * 设置动画时长,单位是毫秒 */ValueAnimator setDuration(long duration)/** * 获取ValueAnimator在运动时,当前运动点的值 */Object getAnimatedValue();/** * 开始动画 */void start()/** * 设置循环次数,设置为INFINITE表示无限循环 */void setRepeatCount(int value)/** * 设置循环模式 * value取值有RESTART,REVERSE, */void setRepeatMode(int value)/** * 取消动画 */void cancel()

    效果:

    e65a25121ceaa74f9382638b48e2b5ff.gif

    二、自定义插值器

    1.插值器的理解

    首先看看自动自定义的插值器 匀速插值器: 看看继承关系:LinearInterpolator---继承--->BaseInterpolator---继承--->Interpolator---实现-->TimeInterpolator 最后看看TimeInterpolator都写了啥: 只定义了一个getInterpolation(float input)方法。

    package android.animation;/** * A time interpolator defines the rate of change of an animation. This allows animations * to have non-linear motion, such as acceleration and deceleration. */public interface TimeInterpolator {    /**     * Maps a value representing the elapsed fraction of an animation to a value that represents     * the interpolated fraction. This interpolated value is then multiplied by the change in     * value of an animation to derive the animated value at the current elapsed animation time.     *     * @param input A value between 0 and 1.0 indicating our current point     *        in the animation where 0 represents the start and 1.0 represents     *        the end     * @return The interpolation value. This value can be more than 1.0 for     *         interpolators which overshoot their targets, or less than 0 for     *         interpolators that undershoot their targets.     */    float getInterpolation(float input);}

    LinearInterpolator的定义

    public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {    public LinearInterpolator() {    }    public LinearInterpolator(Context context, AttributeSet attrs) {    }    public float getInterpolation(float input) {        return input; //数值进度与时间同步    }    /** @hide */    @Override    public long createNativeInterpolator() {        return NativeInterpolatorFactoryHelper.createLinearInterpolator();    }}

    AccelerateInterpolator开始慢,后面一直加速插值器,也叫幂函数插值器,核心方法

     public float getInterpolation(float input) {        if (mFactor == 1.0f) {            return input * input;        } else {            //返回的是时间的次幂数,比如 input=3,mDoubleFactor=2,            //那么返回的就是,3的2次方,就是9            //所以会按照几何倍增,这是一个幂函数            return (float)Math.pow(input, mDoubleFactor);         }    }

    所有的速度都离不开这个方法:getInterpolation

    而最为关键的就是input这个数字。以下是经典解释:

    input参数代表了当前动画的进度,而返回值则代表了当前动画的数值进度。

    上面的匀速,返回的就是时间的值,所以,动画进度和动画的数值持平。 幂函数的时候,随着动画进度的增加,动画的数值进度也就越来越大,从而一直加速。

    input的取值范围是0~1之间,返回值可以超过1,也可以小于0,超过1表示已经超过目标位置,小于0表示远离初始位置。

    简单的公式就是

    y= -> x

    y代表返回的值,也就是动画需要的数值进度,x代表时间进度,->则是通过一些数学手段,来得到想要的y值。

    • 当一些动画定义这些插值器的时候,返回的数值进度越大,速度越快。比如你在匀速运动的时候,时间进度是0.5s,数值进度也是0.5,那就是匀速运动。

    2.定义一个简单的插值器

    我们用数学中的定义来做一个插值器。 y=1-x 把进度反过来,当进度传入0的时候,数值进度已经在目标位置了。当传入1时,数值则在刚开始的位置。

      class FiveInterpolator implements TimeInterpolator {        @Override        public float getInterpolation(float input) {            return 1-input;        }    }

    valueAnimator.setInterpolator(``new ``FiveInterpolator())``; 一个简单的自定义插值器就完成了。

    三、Evaluator

    • Evaluator是数值转换器,就是将数值进度转化为具体的数值。
    • 就是0~400的数值变换,当数值进度是50%的时候,那通过Evaluator来转换,就变成了200
    • oflnt()函 数对应 Evauator 类名为 IntEvauaor ,而 ofFloat()函数对应的 Evauator 类名为 FloatEvaluator

    自定义数值转换器:

         //自定义数值转换器    class MyFloatEvaluator implements TypeEvaluator{        /**         * @param fraction 代表数值进度的值,就是上面getInterpolation()的返回值         * @param startValue  代表ofFloat(Float startValue,Float endValue)         * @param endValue         * */        @Override        public Float evaluate(float fraction, Float startValue, Float endValue) {            //初始值            Float startFloat=startValue;            //当前值=初始值+总值*进度            Float inputValue=startFloat+(endValue-startFloat)*fraction;            return inputValue;        }    }

    使用:

    valueAnimator.setEvaluator(new MyFloatEvaluator());

    所以可以通过插值器和数值转化器来改变控件的数值变化

    valueAnimator.setInterpolator(new FiveInterpolator());valueAnimator.setEvaluator(new MyFloatEvaluator());

    四、ArgbEvaluator

    ArgbEvaluator可以把颜色转换过渡。 具体实现:

     //颜色的数值变换    public void doColorAnimation(){        ValueAnimator valueAnimator=ValueAnimator.ofInt(0xffffff00,0xff0000ff);        valueAnimator.setEvaluator(new ArgbEvaluator());        valueAnimator.setDuration(3000);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                int curValue=(int)animation.getAnimatedValue();                valueTV.setBackgroundColor(curValue);            }        });        valueAnimator.start();    }

    效果:

    af61ae40f89393ca3057a0a8a0e0fc9e.gif

    颜色必须包含ARGB四个值。

    125d530f36bd367abd086f5e4d6ea530.png

    五、ValueAnimation-ofObject

    首先看看这个方法是如何传值的。

    public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {        ValueAnimator anim = new ValueAnimator();        anim.setObjectValues(values);        anim.setEvaluator(evaluator);        return anim;    }

    TypeEvaluator evaluator需要传入自定义的数值转换器 Object... values可变长参数

    实例 实现一个字母从A到Z的过程

    public void doObjectValue() {        ValueAnimator valueAnimator = ValueAnimator.ofObject(new CharInterpolator(), new Character('A'), new Character('Z'));        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                char str = (char) animation.getAnimatedValue();                valueTV.setText(String.valueOf(str));            }        });        valueAnimator.setDuration(7000);        valueAnimator.setInterpolator(new AccelerateInterpolator());        valueAnimator.start();    }    class CharInterpolator implements TypeEvaluator {        @Override        public Character evaluate(float fraction, Character startValue, Character endValue) {            int startInt = (int) startValue;  //ASCII转换   A代表56 以此递增            int endInt = (int) endValue;            int curInt = (int) (startInt + fraction * (endInt - startInt));            char result = (char) curInt;            return result;        }    }

    效果:

    a30e3eff47307d48db8ff95429b6d865.gif

    六、ObjectAnimator

    ObjeceAnimation--继承--->ValueAnimation 与控件之间相关联,从监听动画中解放出来。 先看看这个方法:

    ObjectAnimator ofFloat(Object target, String propertyName, float... values)

    具体使用

      public void doObjectAnimationByAlpha(){        ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(valueTV,"alpha",1,0,1);        objectAnimator.setDuration(6000);        objectAnimator.start();    }

    Object target要控制的控件 String propertyName要改变的动画效果 float... values传入的具体变化值 具体效果就是跟视图动画中设置的动画是一样的效果,透明度从1到0再到1. “alpha”中,是对应view中的setAlpha()方法,后面的可变成参数就是可以传入具体是变换数值。 看看view中有多少个set函数:

    透明度:alpha

    setAlpha(@FloatRange(from=0.0, to=1.0) float alpha)  //透明度

    旋转角度:rotation,rotationX,rotationY

    setRotation(float rotation) //围绕Z轴旋转,Z轴指的是垂直屏幕的方向setRotationX(float rotationX)  //围绕X轴旋转setRotationY(float rotationY)  //围绕Y轴旋转

    平移:translationX,translationY

    setTranslationX(float translationX)   //X轴屏幕,右为正方向,当前控件为原点setTranslationY(float translationY)

    缩放:scaleX,scaleY

    setScaleX(float scaleX) //X轴缩放setScaleY(float scaleY)

    看看旋转是三个效果:

     public void doObjectAnimationByAlpha(){        ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(valueTV,"rotationY",360);        objectAnimator.setDuration(6000);        objectAnimator.start();    }

    Z轴:

    071df6af31d7b51d7189b5fcf0600155.gif

    X轴:

    c8cda4e539d23ef7fa1d3d233344aafe.gif

    Y轴:

    9a84e041db0cf85ec8a0c6eb405098b5.gif

    七、自定义ObjectAnimator

    因为ObjectAnimator是通过set来反射实现的,所以自己也可以通过这样的操作来实现自己view的set函数,从而实现简单的动画效果。

    1.自定义view的set函数

    FallingBallImageView.java

    public class FallingBallImageView extends ImageView {    public FallingBallImageView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public void setFallingPos(Point pos){        layout(pos.x,pos.y,pos.x+getWidth(),pos.y+getHeight());    }}

    布局使用

    set函数的名字是setFallingPos,所以在传递反射函数名字的时候,应该是fallingPos或者FallingPos,必须是这两个名字中其中一个的格式,否则就不会正确反射。参数类型是Point,所以使用函数是ofObject()。

    2.自定义Evaluator

     class DivEvaluator implements TypeEvaluator {        Point point = new Point();        @Override        public Point evaluate(float fraction, Point startValue, Point endValue) {            point.x = (int) (startValue.x + (endValue.x - startValue.x) * fraction);            if (fraction * 2 <= 1) {                point.y = (int) (startValue.y + (endValue.y - startValue.y) * fraction);            } else {                point.y = endValue.y;            }            return point;        }    }

    3.实现最终反射调用

      public void doObjectAnimationByDiv() {        ObjectAnimator objectAnimator=ObjectAnimator                .ofObject(                        ballImageView,  //自定义view的小球                        "FallingPos",   //反射名字,FallingPos或者fallingPos都可以                        new DivEvaluator(), //自定义转换器                        new Point(0,0),     //起始坐标                        new Point(300,300)); //目标坐标        objectAnimator.setDuration(4000);   //动画时长        objectAnimator.start();    }

    4.效果

    5e4fc16381488ec79cb90c7f7a0d1246.gif

    5.get函数

    当我们在上述函数的时候,ofObject()传的都是可变长的参数,也就是两个参数以上,当我们只传递一个参数的时候,这个参数只是目标参数,没有初始参数,系统就会默认调用系统自带的get方法,来获得初始值。当没有这个get方法的时候,就会报错,以至于崩溃。 所以想传递一个参数,就需要自定义get()方法,返回的,就是初始值。对应名字也和set的名字类似。 setFallingPos(Point pos)的名字就是getFallingPos(Point pos)

    在自定义view中加入get方法:返回控件的初始Point

     public Point getFallingPos() {        int[] location = new int[2];        this.getLocationOnScreen(location);        return new Point(location[0], location[1]);    }

    八、AnimatorSet

    1.AnimatorSet理解和使用

    AnimatorSet组合动画,对ValueAnimation和ObjectAnimation都有一样的效果。 有两个播放方法:只管播放的时间,不管动画个体是如何操作的,不管动画的执行时间,循环次数等。 playSequentially() 是顺序播放,当前一个动画播放完毕以后,才会执行下一个动画。当前一个动画是无限循环时,后一个动画也就无法播放。有两个构造方法。

    playSequentially(Animator... items)playSequentially(List items)

    playTogether() 是一起播放,同一个时间内,在列表中所有动画同一时间启动。

    playTogether(Animator... items)playTogether(Collection items)

    具体实例,有一个缩放动画和位移动画,分别实现同时播放和顺序播放。

     public void doAnimationSet() {        //缩放        ObjectAnimator objectAnimatorScaleY = ObjectAnimator.ofFloat(ballImageView, "scaleY", 0.0f, 1.6f, 1.0f);        //平移        ObjectAnimator objectAnimatorTranslationX = ObjectAnimator.ofFloat(ballImageView, "translationX", 400);        //组合动画        AnimatorSet animator = new AnimatorSet();        //每个动画的播放时间        animator.setDuration(3000);        //顺序播放        animator.playSequentially(objectAnimatorScaleY, objectAnimatorTranslationX);        //一起播放        animator.playTogether(objectAnimatorScaleY, objectAnimatorTranslationX);        animator.start();    }

    同时播放:动画效果同时体现出来,缩放和位移

    70eb79a431f77e466d11888bb7e808a7.gif

    顺序播放:先缩放完毕再位移

    81b3d5ea696712e779617a99ed514cb6.gif

    2.AnimatorSet.Builder

              //组合动画        AnimatorSet animator = new AnimatorSet();        //目标动画        AnimatorSet.Builder builder=animator.play(objectAnimatorScaleY);        //执行目标动画后再执行该动画        builder.after(objectAnimatorScaleY);        //执行该动画后再执行目标动画        builder.before(objectAnimatorScaleY);        //和目标动画一起播放        builder.with(objectAnimatorScaleY);        //延迟时间执行目标动画        builder.after(3000);        //串行方式        AnimatorSet animator = new AnimatorSet();        AnimatorSet.Builder builder=animator            .play(objectAnimatorScaleY)            .after(objectAnimatorScaleY)            .before(objectAnimatorScaleY);
            //如果AnimatorSet设置了动画时长,循环次数等,都以AnimatorSet为准,单个设置不起作用。        //每个动画的播放时间        animator.setDuration(3000);
              //所有的动画都集中于这个控件上,其它的不起作用        animator.setTarget(ballImageView);

    九、实例-卫星菜单

    1.实现原理

    实现一个放射卫星的效果,点击一下,放射出菜单,再点击一下,收回菜单。 原理就是,将所有的菜单重叠在一起,点击最上面的菜单,按照不同的角度,实现位移,缩放,透明度的效果,将下面的菜单都位移出去。看看位移的计算方式,每个菜单,与主菜单都形成了直角形式,水平X轴的位移和Y轴的水平位移都可以计算出来。 就是从主菜单,位移到不同位置的X轴和Y轴。

    553b903f443f0c5b4cb61627376721eb.png

    2.布局

    布局非常简单,全部控件叠加在一起,而且子菜单的属性全部一致,省略了一些重复的空间。

    <?xml version="1.0" encoding="utf-8"?>                            

    3.java代码

    核心思想就是,添加要控制的子菜单,开启动画方法,关闭动画方法。

    public class ExampleActivity extends BaseActivity {    private boolean mIsMenuOpen = false;    private Button mMainBtn, mRockBtn, mAirBtn, mTrainBtn, mCarBtn, mMotorbikeBtn, mBicycleBtn, mWalkBtn;    List mBtnArray;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        initView();        OnClick();    }    public void initView() {        setContentView(R.layout.activity_example);        mMainBtn = findViewById(R.id.mainBtn);        mRockBtn = findViewById(R.id.rockBtn);        mAirBtn = findViewById(R.id.airBtn);        mTrainBtn = findViewById(R.id.trainBtn);        mCarBtn = findViewById(R.id.carBtn);        mMotorbikeBtn = findViewById(R.id.motorbikeBtn);        mBicycleBtn = findViewById(R.id.bicycleBtn);        mWalkBtn = findViewById(R.id.walkBtn);        //添加子菜单        mBtnArray = new ArrayList();        mBtnArray.add(mRockBtn);        mBtnArray.add(mAirBtn);        mBtnArray.add(mTrainBtn);        mBtnArray.add(mCarBtn);        mBtnArray.add(mMotorbikeBtn);        mBtnArray.add(mBicycleBtn);        mBtnArray.add(mWalkBtn);    }    public void OnClick() {        mMainBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                switchAnimation();            }        });        mRockBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(ExampleActivity.this, "你选择了火箭出行!", Toast.LENGTH_SHORT).show();            }        });    }    //开关    public void switchAnimation() {        if (!mIsMenuOpen) {            mIsMenuOpen = true;            for (int i = 0; i < mBtnArray.size(); i++) {                doAnimationOpen(mBtnArray.get(i), i, mBtnArray.size(), 500);            }        } else {            mIsMenuOpen = false;            for (int i = 0; i < mBtnArray.size(); i++) {                doAnimationClose(mBtnArray.get(i), i, mBtnArray.size(), 500);            }        }    }    /**     * 开启动画/展开菜单     * @param view   要控制的控件/子菜单     * @param index  要控制控件的顺序     * @param total  子菜单的总数     * @param radius 主菜单到子菜单的距离/半径     * */    private void doAnimationOpen(View view, int index, int total, int radius) {        //显示菜单        if (view.getVisibility() != View.VISIBLE) {            view.setVisibility(View.VISIBLE);        }        //计算每个菜单的角度,toRadians()将度数转换为弧度        //七个子菜单,有六个夹角角,180/(7-1)*2  2代表第二个夹角        double degree = Math.toRadians(180) / (total - 1) * index;        //X轴位移        int translationX = -(int) (radius * Math.sin(degree));        //Y轴位移        int translationY = -(int) (radius * Math.cos(degree));        AnimatorSet animatorSet = new AnimatorSet();        //动画合集        animatorSet.playTogether(                //从原来控件的位置往X轴移动多少                ObjectAnimator.ofFloat(view, "translationX", 0, translationX),                //从原来控件的位置往Y轴移动多少                ObjectAnimator.ofFloat(view, "translationY", 0, translationY),                //X轴缩放                ObjectAnimator.ofFloat(view, "scaleX", 0.01f, 1f),                //Y轴缩放                ObjectAnimator.ofFloat(view, "scaleY", 0.01f, 1.0f),                //透明度                ObjectAnimator.ofFloat(view, "alpha", 0.01f, 1.0f)        );        animatorSet.setDuration(500);        animatorSet.start();    }    //关闭菜单/动画    private void doAnimationClose(View view, int index, int total, int radius) {        if (view.getVisibility() != View.VISIBLE) {            view.setVisibility(View.VISIBLE);        }        double degree = Math.toRadians(180) / (total - 1) * index;        int translationX = -(int) (radius * Math.sin(degree));        int translationY = -(int) (radius * Math.cos(degree));        AnimatorSet animatorSet = new AnimatorSet();        animatorSet.playTogether(                ObjectAnimator.ofFloat(view, "translationX", translationX, 0),                ObjectAnimator.ofFloat(view, "translationY", translationY, 0),                ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 0.01f),                ObjectAnimator.ofFloat(view, "scaleY", 1.0f, 0.01f),                ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.01f)        );        animatorSet.setDuration(500);        animatorSet.start();    }}

    3.效果

    f1e003c1a120b7ef3634653f4447d6e0.gif

    十、XML实现Animator

    1.animator

    在animator下建立animator.xml

    0087f0e9c0c591b4716cdb56c51c462f.png

    xml代码:

    <?xml version="1.0" encoding="utf-8"?>

    java代码使用

      ValueAnimator valueAnimator=(ValueAnimator)AnimatorInflater.loadAnimator(                                ExampleActivity.this,                                R.animator.animator);                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                    @Override                    public void onAnimationUpdate(ValueAnimator animation) {                        int offset=(int)animation.getAnimatedValue();                        mRockBtn.layout(offset,offset,mRockBtn.getWidth()+offset,mRockBtn.getHeight()+offset);                    }                });                valueAnimator.start();

    2.ObjectAnimator

    object_animator.xml

    <?xml version="1.0" encoding="utf-8"?>

    java代码使用

      ObjectAnimator animator=(ObjectAnimator)AnimatorInflater.loadAnimator(                        ExampleActivity.this,                        R.animator.object_animator);                animator.setTarget(mAirBtn);                animator.start();

    十一、后语

    包括其它的知识点,都只能说一些基础的内容,很多方法和拓展知识都没有说到,需要自己去探索,多阅读SDK源码。属性动画,有一些高级的内容,后续会持续拓展。

    编程中我们会遇到多少挫折?表放弃,沙漠尽头必是绿洲。

    展开全文
  • 属性动画的出现,弥补了补间动画的不足之处,补间动画,只是改变了表面上的东西,但是其中属性并未改变,而属性动画相反,改变了表面上的东西,并且也更改了其属性。 类:ObjectAnimator 用于操作属性动画的类 ...
  • ScaleAnimation即缩放动画,应用场景特别多,比如常见的隐藏菜单点击显示 下面我分两种方式来介绍ScaleAnimation如何使用。 1. xml文件形式 文件名:anim_scale_in.xml 效果:呈现view放大显示效果 源码: &...
  • 缩放动画(ScaleAnimation)简介 以控件的中心点为中心做缩小或放大的动作,缩放动画可以实现view有小到大或者由大到小的缩放效果。 缩放动画属性 缩放动画使用scale标签标示,主要有一下几个属性 属性 描述 ...
  • Android 平移动画 缩放动画=集合动画,实现开机启动页 通过线程休眠事件跳转到主界面,Android 平移动画 缩放动画->实现开机启动页: 1、通过集合动画 线程实现开机启动动画界面。 2、设置了休眠时间,休眠过后实现...
  • 在上一篇,简要的介绍了Android动画分类及基本区别,本篇文章将会详细接收Android补间动画中的缩放动画各种使用方法,方便自己及广大开发人员在需要时快速查看。 话不多说,我们先以一个GIF图来展示具体效果。 2...
  • 用 AnimationUtils 和 xml 的方式,加载指定的缩放动画。 Animation scaleAnimation = AnimationUtils.loadAnimation(mContext, R.anim.scale_animation); scaleAnimation.setFillAfter(true); mImageView....
  • Android 点击有缩放动画的imageview
  • Android 相机拍照按钮缩放动画 前言 之前一直想做一个关于相机按钮的动态缩放动画,正好最近有时间整理了以下 演示 正文 round_border.xml 首先,第一步,我们完成其外部的圆形线,使用shape即可。 <?xml version=...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,028
精华内容 1,211
关键字:

缩放动画android