美文网首页
Android属性动画

Android属性动画

作者: Sky_Blue | 来源:发表于2020-04-29 15:08 被阅读0次
    一、属性动画
    1. 定义属性
    2. 提供get set方法
    3. 使用ObjectAnimator
    二、ObjectAnimator 、PropertyValuesHolder 用法
    public class CircleView extends View {
        private Paint mPaint;
        private float radius;
    
        public CircleView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(Color.RED);
        }
    
        public float getRadius() {
            return radius;
        }
    
    
        public void setRadius(float radius) {
            this.radius = radius;
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, mPaint);
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        private CircleView mCircleView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mCircleView = findViewById(R.id.cv);
    
            // 1. 半径从0到50dp
            ObjectAnimator animator = ObjectAnimator
                    .ofFloat(mCircleView,
                            "radius",
                            Utils.dip2px(50)
                    );
            animator.setDuration(1500);
            animator.setStartDelay(1000);
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    // 2. 从左向右移动:中间慢两边快
                    translate();
                }
            });
            animator.start();
        }
    
        private void translate() {
            // 2. 从左向右移动:中间慢两边快
            int width = ((ViewGroup) mCircleView.getParent()).getWidth()-Utils.dip2px(200);
            Keyframe frame1=Keyframe.ofFloat(0.0f,0);
            Keyframe frame2=Keyframe.ofFloat(0.1f,0.2f*width);
            Keyframe frame3=Keyframe.ofFloat(0.8f,0.6f*width);
            Keyframe frame4=Keyframe.ofFloat(0.9f,0.9f*width);
            Keyframe frame5=Keyframe.ofFloat(1f,1f*width);
            PropertyValuesHolder holder=PropertyValuesHolder.ofKeyframe("translationX",
                    frame2,frame3,frame1,frame4,frame5);
            ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mCircleView, holder);
            animator.setDuration(1500);
            animator.start();
            
        }
    }
    
    三、TypeEvaluator用法
    public class PointView extends View {
        private Point point = new Point(0, 0);
        private Paint mPaint;
        private int radius = Utils.dip2px(25);
    
        public PointView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(Color.RED);
        }
    
        public Point getPoint() {
            return point;
        }
    
        public void setPoint(Point point) {
            this.point = point;
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            // 绘制一个圆:
            canvas.drawCircle(point.x + radius, point.y + radius, radius, mPaint);
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        private PointView mPointView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mPointView = findViewById(R.id.pv);
    
            // 最终移动的点的位置
            Point endPoint = new Point(Utils.dip2px(200), Utils.dip2px(300));
            // 动画效果:圆按对角线移动
            ObjectAnimator animator = ObjectAnimator.ofObject(mPointView, "point",
                    new PointTypeEvaluator(), endPoint);
            animator.setDuration(2000);
            animator.setInterpolator(new DecelerateInterpolator());
            animator.setStartDelay(1000);
            animator.start();
    
        }
    
        /**
         * 自定义TypeEvaluator
         */
        static class PointTypeEvaluator implements TypeEvaluator<Point> {
    
            @Override
            public Point evaluate(float fraction, Point startValue, Point endValue) {
                // 计算下一个点
                int x = (int) (startValue.x + (endValue.x - startValue.x) * fraction);
                int y = (int) (startValue.y + (endValue.y - startValue.y) * fraction);
                return new Point(x, y);
            }
        }
    }
    
    六、综合案例:翻转的View
    /**
     * 翻转的View
     */
    public class FancyFlipView extends View {
        private Bitmap mBitmap;
        private Paint mPaint;
        private Camera mCamera;
        private int iconWidth;
        private int iconHeight;
        private int mStart;
    
        // 顶部翻转角度
        private float topFlip=0;
        // 底部翻转角度
        private float bottomFlip=0;
        // 整体旋转角度
        private float flipRotation=0;
    
        public FancyFlipView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public static final int ICON_WIDTH = 150;
    
        {
            mCamera = new Camera();
    
            mCamera.setLocation(0, 0, Utils.getZForCamera());
            mBitmap = Utils.getBitmap(getContext(), R.drawable.icon, Utils.dip2px(ICON_WIDTH));
            iconWidth = mBitmap.getWidth();
            iconHeight = mBitmap.getHeight();
            // 这个值可以随便定
            mStart = iconWidth / 2;
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            // 整体改成左右了
    
            // Camera 三维变换: 倒着写
    
            // 绘制上半部:倒着写
            canvas.save();
            canvas.translate(iconWidth / 2 + mStart, iconHeight / 2+mStart);
            canvas.rotate(-flipRotation);
            mCamera.save();
            mCamera.rotateY(topFlip);// 底部翻转
            mCamera.applyToCanvas(canvas);
            mCamera.restore();
            canvas.clipRect(-iconWidth , -iconHeight , 0 , iconHeight);
            canvas.rotate(flipRotation);
            canvas.translate(-(iconWidth / 2 + mStart), -(iconHeight / 2+mStart));
            canvas.drawBitmap(mBitmap, mStart, mStart, mPaint);
            canvas.restore();
    
            // 绘制下半部:倒着写
            // 1. 将图片中心点移动到左上角
            // 2. 旋转图片
            // 2. 裁剪图片下半部分
            // 3. 将图片中心移回去
            canvas.save();
            canvas.translate(iconWidth / 2 + mStart, iconHeight / 2+mStart);
            canvas.rotate(-flipRotation);
            mCamera.save();
            mCamera.rotateY(bottomFlip);// 底部翻转
            mCamera.applyToCanvas(canvas);
            mCamera.restore();
            canvas.clipRect(0 , -iconHeight, iconWidth , iconHeight );
            canvas.rotate(flipRotation);
            canvas.translate(-(iconWidth / 2 + mStart), -(iconHeight / 2+mStart));
            canvas.drawBitmap(mBitmap, mStart, mStart, mPaint);
            canvas.restore();
    
        }
    
        public float getTopFlip() {
            return topFlip;
        }
    
        public void setTopFlip(float topFlip) {
            this.topFlip = topFlip;
            invalidate();
        }
    
        public float getBottomFlip() {
            return bottomFlip;
        }
    
        public void setBottomFlip(float bottomFlip) {
            this.bottomFlip = bottomFlip;
            invalidate();
        }
    
        public float getFlipRotation() {
            return flipRotation;
        }
    
        public void setFlipRotation(float flipRotation) {
            this.flipRotation = flipRotation;
            invalidate();
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        private FancyFlipView mFlipView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mFlipView = findViewById(R.id.pv);
    
            // 右边向中间翻转45度
            ObjectAnimator bottomFlip = ObjectAnimator.ofFloat(mFlipView, "bottomFlip", -45);
            bottomFlip.setDuration(500);
    
            // 旋转270度:Y 轴和 X轴相当于对换
            ObjectAnimator flipRotation = ObjectAnimator.ofFloat(mFlipView, "flipRotation", 270);
            flipRotation.setDuration(1500);
    
            // 左边向中间翻转45度(旋转270度后,这条边在上面了)
            ObjectAnimator topFlip = ObjectAnimator.ofFloat(mFlipView, "topFlip", 45);
            topFlip.setDuration(500);
    
            AnimatorSet set=new AnimatorSet();
            set.setStartDelay(500);
            // 按顺序执行
            set.playSequentially(bottomFlip,flipRotation,topFlip);
            set.start();
        }
    
    
    }
    

    相关文章

      网友评论

          本文标题:Android属性动画

          本文链接:https://www.haomeiwen.com/subject/hrhmmhtx.html