如何在自定义视图中为Drawable设置动画?

时间:2017-07-26 21:37:51

标签: android animation android-animation android-custom-view android-drawable

我目前有一个带有Drawable资源的自定义视图,我希望动画将其从一个位置移动到另一个位置。我知道有两种方法可以实现PropertyAnimation,您可以使用ValueAnimationObjectAnimation来实现。但两者都没有找到关于如何使用Drawable而不是View的Google文档的任何信息。 This是我发现的唯一与我的问题类似的示例,因此我尝试在我的代码中实现它:

MainActivity

public class MainActivity extends AppCompatActivity {

    private Button animate;
    private CustomView mView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mView = new CustomView(MainActivity.this);

        animate = (Button) findViewById(R.id.animate);
        animate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mView.startAnimation();
            }
        });

    }
}

CustomView

public class CustomView extends View {

    private Drawable drawable;
    private Rect drawableRect;
    private int newPos;

    public CustomView(Context context) {
        super(context);

        drawable = ContextCompat.getDrawable(context, R.drawable.my_drawable);
        drawableRect= new Rect();
        newPos = 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        ...
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        drawableRect.left = 0;
        drawableRect.top = newPos;
        drawableRect.right = drawable.getIntrinsicWidth();
        drawableRect.bottom = newPos + drawable.getIntrinsicHeight();

        drawable.setBounds(drawableRect);
        drawable.draw(canvas);

    }

    public void startAnimation() {

        ValueAnimator animator = ValueAnimator.ofFloat(0, 200);
        animator.setDuration(1500);

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                newPos = ((Float) valueAnimator.getAnimatedValue()).intValue();
                CustomView.this.invalidate();
            }
        });

        animator.start();
        invalidate();

    }

}

但没有效果。 newPos的值正确更改(使用Logs检查)并更新屏幕(使用曲面更新进行检查)但Drawable不会移动。我究竟做错了什么?希望得到任何帮助。

2 个答案:

答案 0 :(得分:2)

我尝试运行代码CustomView,效率很高,它有动画。

您确定执行方法startAnimation吗?

我将startAnimation()添加到构造NoteCustomView,我可以在UI完成加载时看到动画。

下面的代码,我使用ic_launcher作为drawable。我将NoteCustomView添加到活动的布局xml。

public class NoteCustomView extends View {

    private Drawable drawable;
    private Rect drawableRect;
    private int newPos;

    public NoteCustomView(Context context) {
        this(context, null);

    }

    public NoteCustomView(final Context context, @Nullable final AttributeSet attrs) {
        super(context, attrs);
        drawable = ContextCompat.getDrawable(context, R.mipmap.ic_launcher_round);
        drawableRect= new Rect();
        newPos = 0;
        startAnimation();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        drawableRect.left = 0;
        drawableRect.top = newPos;
        drawableRect.right = drawable.getIntrinsicWidth();
        drawableRect.bottom = newPos + drawable.getIntrinsicHeight();

        drawable.setBounds(drawableRect);
        drawable.draw(canvas);

    }

    public void startAnimation() {

        ValueAnimator animator = ValueAnimator.ofFloat(0, 200);
        animator.setDuration(1500);

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                newPos = ((Float) valueAnimator.getAnimatedValue()).intValue();
                NoteCustomView.this.invalidate();
            }
        });

        animator.start();
        invalidate();

    }

}

答案 1 :(得分:0)

周恩旭最终带我去解决方案。我在alert(number.toLocaleString("hi-IN")); 中犯了一个愚蠢的错误,因为我正在创建对MainActivity的新引用:

CustomView

并尝试使用该对象引用进行动画处理。通过将其替换为:

来解决这个问题
mView = new CustomView(MainActivity.this);