zoukankan      html  css  js  c++  java
  • 属性动画 基本使用案例 [MD]

    博文地址

    我的GitHub我的博客我的微信我的邮箱
    baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

    基本使用演示

    MainActivity

    // 可操控的属性有:alpha;x/y;scaleX/scaleY;rotation/rotationX/rotationY;transitionX/transitionY;pivotX/pivotY
    public class MainActivity extends ListActivity {
        private ImageView iv_src;
        private boolean b = true;
    
        private String[] array = {"重启当前Activity,启动一个新的Activity",
            "最简单的ObjectAnimator,控制scaleX、rotationX",
            "不存在get/set方法时不会有任何效果
    为Object的某个属性手动提供get/set方法",
            "只有set没有get方法时,get的值不存在,但是set可以正常使用",
            "监听动画更新:AnimatorUpdateListener
    监听动画状态:AnimatorListener",
            "组合动画:AnimatorSet.playTogether
    组合动画:AnimatorSet.with/before/after",
            "组合动画:AnimatorUpdateListener
    组合动画:PropertyValuesHolder",
            "组合动画:PVHolder + KeyFrame
    View的animate动画,最简洁的属性动画",
            "View的animate动画也可以组合动画
    可以在animate动画前/后执行一些操作",
            "最简单的ValueAnimator,控制translationY
    要明白ValueAnimator只是帮你计算插值的"};
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
            setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array));
    
            iv_src = new ImageView(this);
            iv_src.setBackgroundColor(0x330000ff);
            iv_src.setImageResource(R.drawable.icon);
            getListView().addHeaderView(iv_src);
        }
    
        @Override
        protected void onListItemClick(ListView l, View view, int position, long id) {
            switch (position) {
                case 0:
                    b = !b;
                    Toast.makeText(this, "目前为:" + b, Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    if (b) recreate();//重启当前Activity
                    else startActivity(new Intent(this, SecondActivity.class));
                    break;
                case 2://最简单的ObjectAnimator,控制scaleX、rotationX
                    if (b) ObjectAnimator.ofFloat(iv_src, "scaleX", 1f, 0.1f, 3f, 0.1f, 1f)//X轴缩放
                        .setDuration(1000)
                        .start();
                    else ObjectAnimator.ofFloat(iv_src, "rotationX", 0.0f, 720.0f)//沿X轴旋转
                        .setDuration(500)
                        .start();
                    break;
                case 3://不存在get/set方法时不会有任何效果,可以为Object的某个属性手动提供get/set方法
                    int i = new Random().nextInt(8) + 1;
                    if (b) ObjectAnimator.ofFloat(iv_src, "width", 100 * i)//没任何效果,但并不会报错
                        .setDuration(500)
                        .start();
                    else ObjectAnimator.ofInt(new WrapperView(iv_src), "width", 100 * i) //提供set方法
                        .setDuration(500)
                        .start();
                    break;
                case 4://只有set没有get方法时,get的值不存在,但是set可以正常使用
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        iv_src.setBackgroundColor(Color.WHITE); //有set方法,但是没有get方法,所以get结果为0
                        if (b) ObjectAnimator.ofArgb(iv_src, "backgroundColor", Color.RED)
                            .setDuration(1000)
                            .start();
                        else ObjectAnimator.ofArgb(iv_src, "backgroundColor", Color.RED, Color.GREEN, Color.BLUE)
                            .setDuration(3000)
                            .start();
                    }
                    break;
                case 5://监听动画更新:AnimatorUpdateListener,监听动画状态:AnimatorListener
                    AnimHelper.addAnimListener(iv_src).start();
                    break;
                case 6://组合动画:AnimatorSet.playTogether/with/before/after
                    if (b) AnimHelper.combinedAnimPlayTogether(iv_src).start();
                    else AnimHelper.combinedAnimAfterBefore(iv_src).start();
                    break;
                case 7://组合动画:AnimatorUpdateListener,PropertyValuesHolder
                    if (b) AnimHelper.combinedAnimUpdate(iv_src).start();
                    else AnimHelper.propertyValuesHolder(iv_src).start();
                    break;
                case 8://组合动画:PVHolder + KeyFrame,View的animate动画,最简洁的属性动画
                    if (b) AnimHelper.pVHolderKeyFrame(iv_src).start();
                    else iv_src.animate().y(200 * (new Random().nextInt(8))).setDuration(500).start();//ViewPropertyAnimator
                    break;
                case 9://View的animate动画也可以组合动画,也可以在animate动画前/后执行一些操作
                    if (b) iv_src.animate()
                        .setDuration(1000)
                        .rotation(360 * new Random().nextInt(8))
                        .scaleX(new Random().nextInt(8) * 0.5f)
                        .setInterpolator(new DecelerateInterpolator())
                        .start();
                    else iv_src.animate()
                        .alpha(0.1f)
                        .y(1500)
                        .setDuration(800)
                        .withStartAction(() -> iv_src.setX(300))
                        .withEndAction(() -> {
                            iv_src.setX(0);
                            iv_src.setY(0);
                            iv_src.setAlpha(1f);
                        })
                        .start();
                    break;
                case 10://最简单的ValueAnimator,控制translationY,要明白ValueAnimator只是帮你计算插值的
                    if (b) AnimHelper.valueAnimator(iv_src).start();
                    else AnimHelper.valueAnimator(iv_src, getListView()).start();
                    break;
            }
        }
    }

    View包装类

    View包装类,为不存在get/set方法的属性提供get/set方法

    // View包装类,为不存在get/set方法的属性提供get/set方法
    public class WrapperView {
        private View mTarget;
    
        public WrapperView(View target) {
            mTarget = target;
        }
    
        public int getWidth() {
            return mTarget.getLayoutParams().width;
        }
    
        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
    
        public int getHeight() {
            return mTarget.getLayoutParams().height;
        }
    
        public void setHeight(int height) {
            mTarget.getLayoutParams().height = height;
            mTarget.requestLayout();//Call this when something has changed which has invalidated the layout of this view
        }
    }

    构建动画的工具类

    public class AnimHelper {
    
        //监听动画绘制过程
        public static ObjectAnimator addAnimListener(View view) {
            ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.1f, 1f).setDuration(1000);
            //方法一,实现AnimatorListener接口,监听开始Start、结束End、被取消Cancel、重复Repeat等事件
            //方法二,继承AnimatorListenerAdapter,只实现自己想实现的事件
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    Log.i("bqt", "【onAnimationStart】");
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.i("bqt", "【onAnimationEnd】");
                }
            });
            anim.addUpdateListener(animation -> {
                Float value = (Float) animation.getAnimatedValue();
                view.setRotationX((1 - value) * 360);
                Log.i("bqt", "onAnimationUpdate--" + value); //非常频繁
            });
            return anim;
        }
    
        public static AnimatorSet combinedAnimPlayTogether(View view) {
            ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "scaleX", 0, 2f, 1f);
            ObjectAnimator anim2 = ObjectAnimator.ofFloat(view, "alpha", 0, 1f);
            ObjectAnimator anim3 = ObjectAnimator.ofFloat(view, "rotationY", 360);
    
            AnimatorSet animSet = new AnimatorSet().setDuration(2000);
            animSet.playTogether(anim1, anim2, anim3);
            return animSet;
        }
    
        public static AnimatorSet combinedAnimAfterBefore(View view) {
            ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 2f);
            ObjectAnimator anim2 = ObjectAnimator.ofFloat(view, "scaleY", 0.1f, 1f);
            ObjectAnimator anim3 = ObjectAnimator.ofFloat(view, "x", 0, -view.getWidth(), 0);
            ObjectAnimator anim4 = ObjectAnimator.ofFloat(view, "y", 0, view.getY() + 500f, 0);
            ObjectAnimator anim5 = ObjectAnimator.ofFloat(view, "rotationX", 360 * 2);
    
            AnimatorSet animSet = new AnimatorSet();
            animSet.play(anim1).with(anim2);//anim1,anim2同时执行
            animSet.play(anim2).with(anim3);//anim1,anim2,anim3同时执行
            animSet.play(anim4).after(anim3).before(anim5);//anim4在anim1,anim2,anim3之后,在anim5之前
            animSet.setDuration(1000);
            return animSet;
        }
    
        public static Animator combinedAnimUpdate(View view) {
            //ObjectAnimator anim = ObjectAnimator.ofFloat(view, "包青天", 0.5f, 0.1f, 2f).setDuration(2000);
            ValueAnimator anim = ValueAnimator.ofFloat(0.5f, 0.1f, 2f).setDuration(2000); //效果和上面的ObjectAnimator完全一样
            anim.addUpdateListener(animation -> {
                float cVal = (Float) animation.getAnimatedValue();
                view.setScaleX(cVal);
                view.setAlpha(cVal);
                view.setRotationX(cVal * 360);
            });
            return anim;
        }
    
        public static ObjectAnimator propertyValuesHolder(View view) {
            PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 0.2f, 1f);
            PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 0.8f, 0, 2f);
            PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("rotationY", 360 * 2f, 0);
            return ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ).setDuration(1000);//三个动画是同时执行的
        }
    
        public static ObjectAnimator pVHolderKeyFrame(View view) {
            Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
            Keyframe kf1 = Keyframe.ofFloat(0.5f, 360f);
            Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
            kf1.setInterpolator(new AccelerateInterpolator());
            PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
            return ObjectAnimator.ofPropertyValuesHolder(view, pvhRotation).setDuration(1000);
        }
    
        public static ValueAnimator valueAnimator(View view) {
            ValueAnimator animator = ValueAnimator.ofFloat(0, 800, 0).setDuration(500);//没有设置要操作的【对象】及【对象的属性】
            //animator.setTarget(view);//对ValueAnimator来说,这个方法是空方法(没有意义),因为它不会作用在任何View上
            //对ValueAnimator来说,是通过addUpdateListener,在回调中根据动画的值来手动设置属性的值的
            animator.addUpdateListener(animation -> {
                Float f = (Float) animation.getAnimatedValue();//这里只能强转为of**时指定的类型
                view.setTranslationY(f);//设置要操作的对象的属性。或者你可以使用获取到的值做任何事情
            });
            return animator;
        }
    
        public static ValueAnimator valueAnimator(View view, ListView listView) {
            ValueAnimator animator = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                animator = ValueAnimator.ofArgb(Color.GREEN).setDuration(5000);
                animator.addUpdateListener(animation -> {
                    Integer greenColor = (Integer) animation.getAnimatedValue(); //实时获取值
                    int myColor = (int) (animation.getAnimatedFraction() * Color.YELLOW);
                    int count = listView.getAdapter().getCount();
                    for (int i = 1; i < count; i++) {
                        if (i % 2 == 0) listView.getChildAt(i).setBackgroundColor(greenColor);
                        else listView.getChildAt(i).setBackgroundColor(myColor);
                    }
                });
            }
            return animator;
        }
    }

    自定义 TypeEvaluator 实现抛物线动画效果

    // 自定义TypeEvaluator实现抛物线动画效果
    public class TypeEvaluatorActivity extends Activity {
        private static final int RADIUS_BALL = 10; //小球的半径
        private static final int RADIUS_TRACE = 3; //轨迹的半径
        private ImageView iv_src;
        RelativeLayout layout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
            initView();
            layout = new RelativeLayout(this);
            layout.setBackgroundColor(Color.LTGRAY);
            layout.setOnClickListener(v -> anim());
            layout.addView(iv_src, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            setContentView(layout);
        }
    
        private void initView() {
            Bitmap bitmap = Bitmap.createBitmap(2 * RADIUS_BALL, 2 * RADIUS_BALL, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            paint.setAntiAlias(true);
            paint.setDither(true);
            canvas.drawCircle(RADIUS_BALL, RADIUS_BALL, RADIUS_BALL, paint);
            iv_src = new ImageView(this);
            iv_src.setImageBitmap(bitmap);
        }
    
        private void anim() {
            final int color = 0xFF000000 + new Random().nextInt(0xFFFFFF);
            Point point = new Point();
            ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
            PointF startPointF = new PointF(0, 0);
            PointF endPointF = new PointF(point.x - iv_src.getWidth(), point.y - iv_src.getHeight());
    
            ValueAnimator animator = new ValueAnimator().setDuration(1000);
            animator.setInterpolator(new LinearInterpolator()); //插值器,默认为AccelerateDecelerateInterpolator【慢-快-慢】
            //通过new创建的ValueAnimator必须setObjectValues和setEvaluator,并且一定要先setObjectValues,再setEvaluator
            animator.setObjectValues(startPointF, endPointF);
    
            animator.setEvaluator((TypeEvaluator<PointF>) (fraction, startValue, endValue) -> { //估值器
                //只要能保证:当fraction=0时返回值为startValue,并且当fraction=1时返回值为endValue,就是一个比较合理的函数
                PointF pointF = new PointF();
                pointF.x = startValue.x + fraction * (endValue.x - startValue.x);// x方向匀速移动
                pointF.y = startValue.y + fraction * fraction * (endValue.y - startValue.y);// y方向抛物线加速移动
                return pointF;
            });
    
            animator.addUpdateListener(animation -> {
                PointF pointf = (PointF) animation.getAnimatedValue();
                iv_src.setX(pointf.x);
                iv_src.setY(pointf.y);
                addTrace(pointf, color);
            });
            animator.start();
        }
    
        private void addTrace(PointF pointf, int color) {
            View view = new View(this);
            view.setBackgroundColor(color);
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(2 * RADIUS_TRACE, 2 * RADIUS_TRACE);
            layoutParams.leftMargin = (int) pointf.x + RADIUS_TRACE;
            layoutParams.topMargin = (int) pointf.y + RADIUS_TRACE;
            layout.addView(view, layoutParams);
        }
    }

    使用 LayoutTransition 为布局容器中子View的显示与消失设置过渡动画

    public class LayoutTransitionActivity extends ListActivity {
    
        private GridLayout gl_container;//父布局
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            String[] array = {"点击添加一个View,点击添加的View删除此View"};
            setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array));
    
            gl_container = new GridLayout(this);
            gl_container.setColumnCount(4);
            gl_container.setLayoutTransition(new LayoutTransition());//布局动画,当容器中的视图发生变化时存在过渡的动画效果
            getListView().addFooterView(gl_container);
    
            addCheckBox(LayoutTransition.APPEARING, "APPEARING");//当一个View在VG中【出现】时设置的动画
            addCheckBox(LayoutTransition.CHANGE_APPEARING, "CHANGE_APPEARING");
            //当一个View在ViewGroup中【出现】时,对此View对其他View位置造成影响,对【其他View】设置的动画
            addCheckBox(LayoutTransition.DISAPPEARING, "DISAPPEARING");//当一个View在VG中【消失】时设置的动画
            addCheckBox(LayoutTransition.CHANGE_DISAPPEARING, "CHANGE_DISAPPEARING");
            //当一个View在ViewGroup中【消失】时,对此View对其他View位置造成影响,对【其他View】设置的动画
            addCheckBox(-1, "等价于是否设置xml中GridLayout的animateLayoutChanges属性为true");
        }
    
        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
            Button button = new Button(this);
            button.setText(gl_container.getChildCount() + 1 + "");
            gl_container.addView(button, gl_container.getChildCount());//放置在最后那个位置
            button.setOnClickListener(view -> gl_container.removeView(button));
        }
    
        private void addCheckBox(int transitionType, String text) {
            CheckBox checkBox = new CheckBox(this);
            checkBox.setText(text);
            checkBox.setChecked(true);
            checkBox.setOnCheckedChangeListener((v, isChecked) -> {
                LayoutTransition mTransition = new LayoutTransition(); //默认为全部开启状态,默认的动画效果都是可以更改的
                if (transitionType == -1) mTransition = isChecked ? mTransition : null;
                else mTransition.setAnimator(transitionType, isChecked ? mTransition.getAnimator(transitionType) : null);
                gl_container.setLayoutTransition(mTransition);
            });
            getListView().addFooterView(checkBox);
        }
    }

    使用 LayoutAnimationController 为布局容器中的控件播放同样的动画

    public class LayoutAnimationControllerActivity extends ListActivity {
        LinearLayout linearLayout;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            String[] array = {"点击添加HeaderView",
                "点击添加的HeaderView",
                "移除添加移除View时没任何动画效果",
                "ListView不支持addView操作"//UnsupportedOperationException:addView(View) is not supported in AdapterView
            };
            setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array));
            getListView().setLayoutAnimation(getLayoutAnimationController());//android:layoutAnimation="@anim/layout_anim"
            addFooterView();
        }
    
        private void addFooterView() {
            linearLayout = new LinearLayout(this);
            linearLayout.setOrientation(LinearLayout.VERTICAL);
            new Handler().postDelayed(() -> linearLayout.addView(getView(v -> linearLayout.removeView(v))), 500);
            new Handler().postDelayed(() -> linearLayout.addView(getView(v -> linearLayout.removeView(v))), 1500);
            new Handler().postDelayed(() -> linearLayout.addView(getView(v -> linearLayout.removeView(v))), 3500);
            linearLayout.setLayoutAnimation(getLayoutAnimationController());
            getListView().addHeaderView(linearLayout);
        }
    
        private LayoutAnimationController getLayoutAnimationController() {
            Animation animation = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);//补间动画
            LayoutAnimationController lac = new LayoutAnimationController(animation);//布局动画
            lac.setOrder(LayoutAnimationController.ORDER_NORMAL);//显示顺序 normal=0 默认,reverse=1 倒序,random=2 随机
            lac.setDelay(0.6f);//显示间隔时间,注意单位是秒,可以为70%,也可以是一个浮点数
            return lac;
        }
    
        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
            int index = position - getListView().getHeaderViewsCount();
            if (index == 0) {
                getListView().addHeaderView((getView(view -> getListView().removeHeaderView(view))));
            } else if (index == 1) {
                linearLayout.addView(getView(view -> linearLayout.removeView(view)));
            }
        }
    
        private ImageView getView(View.OnClickListener listener) {
            ImageView iv = new ImageView(this);
            iv.setImageResource(R.drawable.ic_launcher);
            iv.setOnClickListener(listener);
            return iv;
        }
    }

    几十种 Interpolator 演示

    SecondActivity

    public class SecondActivity extends ListActivity {
        private final String[][] array = {INTERPOLATORS1, INTERPOLATORS2, INTERPOLATORS3, INTERPOLATORS4, INTERPOLATORS5, INTERPOLATORS6,};
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
            requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏
            String[] names = {"-1-", "-2-", "-3-", "-4-", "-5-", "-6-", //
                "自定义TypeEvaluator实现抛物线动画效果", //
                "使用LayoutTransition为布局容器中子View的显示与消失设置过渡动画", //
                "使用LayoutAnimationController为布局容器中的控件播放同样的动画",};
            setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, names));
        }
    
        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
            switch (position) {
                case 6:
                    startActivity(new Intent(this, TypeEvaluatorActivity.class));
                    break;
                case 7:
                    startActivity(new Intent(this, LayoutTransitionActivity.class));
                    break;
                case 8:
                    startActivity(new Intent(this, LayoutAnimationControllerActivity.class));
                    break;
                default:
                    Intent intent = new Intent(this, InterpolatorActivity.class);
                    intent.putExtra(InterpolatorActivity.EXTRA_NAME, array[position]);
                    startActivity(intent);
                    break;
            }
        }
    
        public static final String[] INTERPOLATORS1 = new String[]{"EaseBackInInterpolator", "EaseBackInOutInterpolator", "EaseBackOutInterpolator",
            "EaseBounceInInterpolator", "EaseBounceInOutInterpolator", "EaseBounceOutInterpolator", "EaseBreathInterpolator", "EaseCircularInInterpolator",
            "EaseCircularInOutInterpolator", "EaseCircularOutInterpolator",};
        public static final String[] INTERPOLATORS2 = new String[]{"EaseCubicInInterpolator", "EaseCubicInOutInterpolator", "EaseCubicOutInterpolator",
            "EaseExponentialInInterpolator", "EaseExponentialInOutInterpolator", "EaseExponentialOutInterpolator", "EaseInBackInterpolator",
            "EaseInBounceInterpolator", "EaseInCircInterpolator", "EaseInCubicInterpolator",};
        public static final String[] INTERPOLATORS3 = new String[]{"EaseInElasticInterpolator", "EaseInExpoInterpolator", "EaseInOutBackInterpolator",
            "EaseInOutBounceInterpolator", "EaseInOutCircInterpolator", "EaseInOutCubicInterpolator", "EaseInOutElasticInterpolator",
            "EaseInOutExpoInterpolator", "EaseInOutQuadInterpolator", "EaseInOutQuartInterpolator",};
        public static final String[] INTERPOLATORS4 = new String[]{"EaseInOutQuintInterpolator", "EaseInOutSineInterpolator", "EaseInQuadInterpolator",
            "EaseInQuartInterpolator", "EaseInQuintInterpolator", "EaseInSineInterpolator", "EaseOutBackInterpolator", "EaseOutBounceInterpolator",
            "EaseOutCircInterpolator", "EaseOutCubicInterpolator",};
        public static final String[] INTERPOLATORS5 = new String[]{"EaseOutElasticInterpolator", "EaseOutExpoInterpolator", "EaseOutQuadInterpolator",
            "EaseOutQuartInterpolator", "EaseOutQuintInterpolator", "EaseOutSineInterpolator", "EaseQuadInInterpolator", "EaseQuadInOutInterpolator",
            "EaseQuadOutInterpolator", "EaseQuartInInterpolator",};
        public static final String[] INTERPOLATORS6 = new String[]{"EaseQuartInOutInterpolator", "EaseQuartOutInterpolator", "EaseQuintInInterpolator",
            "EaseQuintInOutInterpolator", "EaseQuintOutInterpolator",};
    }

    InterpolatorActivityInterpolatorActivity

    public class InterpolatorActivity extends ListActivity {
        private ObjectAnimator mAnimator;
        private static final String IN_PG_NAME = "com.bqt.anim.interpolator.";
        public static final String EXTRA_NAME = "interpolators";
        private String[] mInterpolators;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
            mInterpolators = getIntent().getStringArrayExtra(EXTRA_NAME); //传过来的名字
            setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mInterpolators));
    
            ImageView iv_src = new ImageView(this);
            iv_src.setBackgroundColor(0x330000ff);
            iv_src.setImageResource(R.drawable.icon);
            getListView().addHeaderView(iv_src);
    
            DisplayMetrics metric = new DisplayMetrics();
            ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
            mAnimator = ObjectAnimator.ofFloat(iv_src, "y", 0, metric.heightPixels, 0).setDuration(1500);
        }
    
        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
            if (position == 0) recreate();
            else anim(position - 1);
        }
    
        private void anim(int position) {
            String name = mInterpolators[position];
            try {
                Class<?> clazz = Class.forName(IN_PG_NAME + name);
                TimeInterpolator interpolator = (TimeInterpolator) clazz.newInstance();
                mAnimator.cancel();
                mAnimator.setInterpolator(interpolator);
                mAnimator.start();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    2019-5-11

  • 相关阅读:
    pytest+allure生成测试报告
    pytest之fixture使用详解
    pytest框架介绍
    使用records库操作SQL并且查询MySQL数据库
    python模块之codecs
    项目总结
    第二阶段团队绩效评分
    软件发布2.0
    “随手记”开发记录day20
    “随手记”开发记录day19
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/10850330.html
Copyright © 2011-2022 走看看