PropertyValuesHolder的使用

来源:互联网 发布:工商业的软件 编辑:程序博客网 时间:2024/05/20 17:26

参考:
PropertyValuesHolder的使用

【HenCoder Android 开发进阶】自定义 View 1-7:属性动画(进阶篇)

同一个动画中改变多个属性:多个动画同时执行

方式一:ViewPropertyAnimator

view.animate()        .scaleX(1)        .scaleY(1)        .alpha(1);

方式二:PropertyValuesHolder

PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("scaleX", 1);PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleY", 1);PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("alpha", 1);ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder1, holder2, holder3)animator.start();

方式三:AnimatorSet (可指定动画顺序)

ObjectAnimator animator1 = ObjectAnimator.ofFloat(...);animator1.setInterpolator(new LinearInterpolator());ObjectAnimator animator2 = ObjectAnimator.ofInt(...);animator2.setInterpolator(new DecelerateInterpolator());AnimatorSet animatorSet = new AnimatorSet();// 两个动画依次执行animatorSet.playSequentially(animator1, animator2);// 两个动画同时执行animatorSet.playTogether(animator1, animator2);// 使用 AnimatorSet.play(animatorA).with/before/after(animatorB)// 的方式来精确配置各个 Animator 之间的关系animatorSet.play(animator1).with(animator2);animatorSet.play(animator1).before(animator2);animatorSet.play(animator1).after(animator2);animatorSet.start();

PropertyValuesHolder的使用

通过设置 Keyframe (关键帧),把同一个动画属性拆分成多个阶段。

//1、设置关键帧//参数:动画进度百分比,动画属性值Keyframe.ofFloat(float fraction, float value)Keyframe.ofInt(float fraction, int value)Keyframe.ofObject(float fraction, Object value)//2、将关键帧添加到PropertyValuesHolder//参数:属性名(需要set/get方法),关键帧KeyframePropertyValuesHolder.ofKeyframe(String propertyName, Keyframe... values)//参数:属性值、属性值PropertyValuesHolder.ofFloat(String propertyName, float... values)//参数:属性值、属性值PropertyValuesHolder.ofInt(Property<?, Integer> property, int... values);//参数:属性值、TypeEvaluator、属性值PropertyValuesHolder.ofObject(String propertyName, TypeEvaluator evaluator, Object... values);//3、添加到ObjectAnimator//参数:执行动画的对象,属性值HolderObjectAnimator.ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)

PropertyValuesHolder使用示例:

KeyframeView

public class KeyframeView extends View {    final float radius = dpToPixel(80);    float progress = 0;    RectF arcRectF = new RectF();    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);    public KeyframeView(Context context) {        super(context);    }    public KeyframeView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public KeyframeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    {        paint.setTextSize(dpToPixel(40));        paint.setTextAlign(Paint.Align.CENTER);    }    public float getProgress() {        return progress;    }    public void setProgress(float progress) {        this.progress = progress;        invalidate();    }    @Override    public void onDraw(Canvas canvas) {        super.onDraw(canvas);        float centerX = getWidth() / 2;        float centerY = getHeight() / 2;        paint.setColor(Color.parseColor("#E91E63"));        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeCap(Paint.Cap.ROUND);        paint.setStrokeWidth(dpToPixel(15));        arcRectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);        canvas.drawArc(arcRectF, 135, progress * 2.7f, false, paint);        paint.setColor(Color.WHITE);        paint.setStyle(Paint.Style.FILL);        canvas.drawText((int) progress + "%", centerX, centerY - (paint.ascent() + paint.descent()) / 2, paint);    }}

Utils

public class Utils {    public static float dpToPixel(float dp) {        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();        return dp * metrics.density;    }}

布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="执行动画" />    <Button        android:id="@+id/firstview"        android:layout_width="200dp"        android:layout_height="200dp"        android:text="我是一个view" />    <com.joanzapata.android.KeyframeView        android:id="@+id/secondview"        android:layout_width="200dp"        android:layout_height="200dp"        android:layout_below="@+id/firstview"        android:layout_marginTop="20dp" /></LinearLayout>

代码:

public class MyActivityI extends AppCompatActivity implements View.OnClickListener {    private Button mButton;    private Button view1;    private KeyframeView view2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_anim);        mButton = (Button) findViewById(R.id.btn);        view1 = (Button) findViewById(R.id.firstview);        view2 = (KeyframeView) findViewById(R.id.secondview);        mButton.setOnClickListener(this);    }    @Override    public void onClick(View v) {        anim1();        anim2();    }    private void anim2() {        // 在 0% 处开始        Keyframe keyframe1 = Keyframe.ofFloat(0, 0);        // 时间经过 50% 的时候,动画完成度 100%        Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 100);        // 时间见过 100% 的时候,动画完成度倒退到 80%,即反弹 20%        Keyframe keyframe3 = Keyframe.ofFloat(1, 80);        PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("progress", keyframe1, keyframe2, keyframe3);        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view2, holder);        animator.setDuration(5000);        animator.start();    }    /**     * PropertyValuesHolder这个类可以先将动画属性和值暂时的存储起来,后一起执行,在有些时候可以使用替换掉AnimatorSet,减少代码量     */    private void anim1() {        //keyframe        Keyframe keyframe1 = Keyframe.ofFloat(0.0f, 0);        Keyframe keyframe2 = Keyframe.ofFloat(0.25f, -30);        Keyframe keyframe3 = Keyframe.ofFloat(0.5f, 30);        Keyframe keyframe4 = Keyframe.ofFloat(1.0f, 0);        PropertyValuesHolder rotation = PropertyValuesHolder.ofKeyframe(View.ROTATION, keyframe1, keyframe2, keyframe3, keyframe4);        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.2f, 1.0f);        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.2f, 1.0f);        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.2f, 1.0f);        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view1, alpha, scaleX, scaleY, rotation);        animator.setInterpolator(new OvershootInterpolator());        animator.setDuration(5000).start();    }}
阅读全文
0 0
原创粉丝点击