0

我目前有一个自定义视图,带有一个Drawable资源,我想将其从一个位置移动到另一个位置。我知道有两种方法可以实现PropertyAnimation,您可以通过使用ValueAnimationObjectAnimation来完成。但两者都没有在Google文档中找到关于如何使用Drawable而不是View的信息。 This是我发现,类似于我的问题的唯一例子,所以我tryed实现它在我的代码:如何在自定义视图中为Drawable创建动画?

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不会移动。我究竟做错了什么?希望在任何帮助。

+0

你是否检查'newPos'是否改变了不同的0?添加一些日志或断点,如果没有,请重试。 – Eselfar

回答

0

周恩旭最终把我带到了解决方案。我在做MainActivity一个愚蠢的错误,因为我是创建一个新的参考CustomView

mView = new CustomView(MainActivity.this); 

,并试图使用该对象引用动画。通过替换它来解决这个问题:

mView = (CustomView) findViewById(R.id.custom_view); 
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(); 

    } 

} 
+0

好吧,这样动画就可以工作,但是如果我从Activity中调用'startAnimation()',它就不起作用。看看我更新的代码。 –

+0

以我的方式,我使用xml,它很高效。也许你没有在Activity的'onCreate()'中添加'addView(mView)'? –

+0

为什么要在'onCreate()'中添加'addView(mView)'?该视图已经用'setContentView()'方法绘制。我只需要对自定义视图的引用,因为我想从活动中启动动画,但这似乎不起作用。 –