Android自定义View动画

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

运行效果:

前言:

Android系统提供了两个动画框架:属性动画框架和View动画框架。 两个动画框架都是可行的选项,但是属性动画框架通常是首选的使用方法,因为它更灵活,并提供更多的功能。 除了这两个框架,还可以使用Drawable动画(即逐帧动画,AnimationDrawable),它允许你加载Drawable资源并逐帧地显示它们。

View动画框架中一共提供了AlphaAnimation(透明度动画)、RotateAnimation(旋转动画)、ScaleAnimation(缩放动画)、TranslateAnimation(平移动画)四种类型的补间动画;并且View动画框架还提供了动画集合类(AnimationSet),通过动画集合类(AnimationSet)可以将多个补间动画以组合的形式显示出来;当然如果对提供的类型动画不满意,可以自定义动画!

View布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".MainActivity">

    <Button
        android:id="@+id/btnAlpha"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="80dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@color/colorAccent"
        android:text="@string/animation_me"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="30sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnRotate"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@color/colorPrimary"
        android:text="@string/rotate_animation"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnAlpha" />

    <Button
        android:id="@+id/btnTranslate"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@color/colorPrimaryDark"
        android:text="@string/translate_animation"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnRotate" />

    <Button
        android:id="@+id/btnScale"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@android:color/holo_orange_dark"
        android:text="@string/scale_animation"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnTranslate" />

    <Button
        android:id="@+id/btnBlend"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@android:color/background_dark"
        android:text="@string/blend_animation"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="30sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnScale" />

    <Button
        android:id="@+id/btnListener"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@android:color/holo_green_dark"
        android:text="@string/listener_animation"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnBlend" />

    <Button
        android:id="@+id/btnCustom"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:background="@android:color/holo_red_light"
        android:text="@string/custom_animation"
        android:textAllCaps="false"
        android:textColor="@android:color/background_light"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnListener" />

</android.support.constraint.ConstraintLayout>

Control层:

 MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btnAlpha,btnRotate,btnTranslate,btnScale,btnBlend,btnListener,btnCustom;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    public void initView(){
        btnAlpha=findViewById(R.id.btnAlpha);
        btnRotate=findViewById(R.id.btnRotate);
        btnTranslate=findViewById(R.id.btnTranslate);
        btnScale=findViewById(R.id.btnScale);
        btnBlend=findViewById(R.id.btnBlend);
        btnListener=findViewById(R.id.btnListener);
        btnCustom=findViewById(R.id.btnCustom);

        btnAlpha.setOnClickListener(this);
        btnRotate.setOnClickListener(this);
        btnTranslate.setOnClickListener(this);
        btnScale.setOnClickListener(this);
        btnBlend.setOnClickListener(this);
        btnListener.setOnClickListener(this);
        btnCustom.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnAlpha:
                 //方法一:Java程序配置动画
//               AlphaAnimation animation=new AlphaAnimation(0,1);//透明度从零到一
//               animation.setDuration(2000);//动画时长
//               v.startAnimation(animation);//按钮开启动画

                 //方法二:使用布局文件来配置动画
                 v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha));
                 break;
            case R.id.btnRotate:
                //方法一:Java程序配置动画
//               RotateAnimation rotateAnimation=new RotateAnimation(0,360,
//                        Animation.RELATIVE_TO_SELF,0.5f,
//                        Animation.RELATIVE_TO_SELF,0.5f);//零到360度,旋转点为控件相对中心
//               rotateAnimation.setDuration(2000);
//               v.startAnimation(rotateAnimation);
                //方法二:使用布局文件来配置动画
                 v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.rotate));
                 break;
            case R.id.btnTranslate:
//                TranslateAnimation translateAnimation=new TranslateAnimation(0,200,
//                        0,200);//从原位置向x、y方向各移动200像素
//                translateAnimation.setDuration(2000);
//                v.startAnimation(translateAnimation);
                v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.translate));
                break;
            case R.id.btnScale:
//                ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1,
//                        Animation.RELATIVE_TO_SELF,0.5f,
//                        Animation.RELATIVE_TO_SELF,0.5f);//缩放从零到一,缩放点相对于自身中心
//                scaleAnimation.setDuration(2000);
//                v.startAnimation(scaleAnimation);
                v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.scale));
                break;
            case R.id.btnBlend:
                //动画集合类AnimationSet
//                AnimationSet animationSet=new AnimationSet(true);//各动画共用动画补间
//                补间动画是一种设定动画开始状态、结束状态,其中间的变化由系统计算补充。
//                animationSet.setDuration(2000);
//
//                RotateAnimation rotateAnimation=new RotateAnimation(0,360,
//                        Animation.RELATIVE_TO_SELF,0.5f,
//                        Animation.RELATIVE_TO_SELF,0.5f);
//                rotateAnimation.setDuration(1000);
//                animationSet.addAnimation(rotateAnimation);//集合中添加子动画
//                ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1,
//                        Animation.RELATIVE_TO_SELF,0.5f,
//                        Animation.RELATIVE_TO_SELF,0.5f);
//                scaleAnimation.setDuration(1000);
//                animationSet.addAnimation(scaleAnimation);
//                v.startAnimation(animationSet);
                v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.blend));
                break;
            case R.id.btnListener:
                Animation animation=AnimationUtils.loadAnimation(MainActivity.this,R.anim.blend);
                animation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                        Toast.makeText(MainActivity.this,"动画开始!",Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        Toast.makeText(MainActivity.this,"动画结束!",Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                        //动画重复执行
                    }
                });
                v.startAnimation(animation);
                break;
            case R.id.btnCustom:
                CustomAnimation customAnimation=new CustomAnimation();
                v.startAnimation(customAnimation);
        }
    }
}

 CustomAnimation.java:

public class CustomAnimation extends Animation {

    //动画初始化,用来设置动画的基本属性
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        setDuration(2000);//设置动画时长
    }

    //该方法用来实现动画,
    // interpolatedTime表示插值器的时间因子,补间时间,取值范围0-1
    // t一个矩阵的封装类,实现动画就是利用矩阵来计算的
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        //t.setAlpha(interpolatedTime);//透明效果

        //Matrix可将一个点映射到另一个点,矩阵中包含了处理缩放、透视以及平移的区域,从而可用于控制实现平移、缩放、旋转等动画效果。
        //t.getMatrix().setTranslate(interpolatedTime*200,interpolatedTime*200);//平移效果

        t.getMatrix().setTranslate((float) (Math.sin(interpolatedTime*20)*50),0);//使用周期函数实现摇头效果
    }
}

资源配置文件:

alpha.xml

扫描二维码关注公众号,回复: 3721473 查看本文章
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0"
    android:toAlpha="1"
    android:duration="2000">
</alpha>

rotate.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:duration="2000"
    android:pivotX="50%"
    android:pivotY="50%">

</rotate>

scale.xml

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0"
    android:toXScale="1"
    android:fromYScale="0"
    android:toYScale="1"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="2000">

</scale>

translate.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="200"
    android:fromYDelta="0"
    android:toYDelta="200"
    android:duration="2000">

</translate>

blend.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:duration="2000">

    <rotate android:fromDegrees="0"
        android:toDegrees="360"
        android:duration="1000"
        android:pivotX="50%"
        android:pivotY="50%">
    </rotate>
    <scale android:fromXScale="0"
        android:toXScale="1"
        android:fromYScale="0"
        android:toYScale="1"
        android:duration="1000"
        android:pivotX="50%"
        android:pivotY="50%">
    </scale>

</set>

技术博客:

Android Animation运行原理详解:https://www.jianshu.com/p/fcd9c7e9937e

Android自定义View--Matrix Camera:http://www.gcssloop.com/customview/matrix-3d-camera

Android中的View动画和属性动画:https://www.jianshu.com/p/b117c974deaf

Android 属性动画(Property Animation) 完全解析 (上):https://blog.csdn.net/lmj623565791/article/details/38067475

猜你喜欢

转载自blog.csdn.net/dpl12/article/details/82970524