0

J'ai actuellement une vue personnalisée avec une ressource Drawable que je veux animer en la déplaçant d'une position à une autre. Je sais qu'il existe deux façons de mettre en œuvre PropertyAnimation, vous pouvez le faire en utilisant ValueAnimation ou ObjectAnimation. Mais avec les deux, je n'ai trouvé aucune information sur Google Docs sur la façon de les utiliser avec un Drawable au lieu d'une vue. This est le seul exemple que je trouve qui est semblable à mon problème, et j'ai tryed à mettre en œuvre dans mon code:Comment animer un Drawable dans une vue personnalisée?

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(); 

    } 

} 

Mais sans effet. La valeur de newPos change correctement (cochée avec Logs) et l'écran est mis à jour (vérifié avec la mise à jour de surface) mais le Drawable ne bouge pas. Qu'est-ce que je fais mal? Espérant n'importe quelle aide.

+0

Avez-vous vérifié que 'newPos' change pour quelque chose de différent de 0? Ajoutez des journaux ou des points de rupture et réessayez si vous ne l'avez pas fait. – Eselfar

Répondre

0

周恩旭 m'a finalement amené à la solution. Je faisais une erreur stupide MainActivity parce que je créais une nouvelle référence à la CustomView:

mView = new CustomView(MainActivity.this); 

et essayer d'animer en utilisant cette référence d'objet. Résolu ceci en le remplaçant par:

mView = (CustomView) findViewById(R.id.custom_view); 
2

J'essaie d'exécuter votre code que le CustomView, c'est efficace, c'est de l'animation.

Etes-vous sûr d'exécuter la méthode startAnimation?

J'ajoute le startAnimation() à la construction NoteCustomView, je peux voir l'animation quand l'interface utilisateur finit la charge.

Code ci-dessous, j'utilise ic_launcher comme dessablable. Et j'ajoute le NoteCustomView à la mise en page xml de l'activité.

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

Ok, donc de cette façon l'animation fonctionne, mais si j'appelle 'startAnimation()' de l'activité cela ne fonctionne pas. Jetez un oeil à mon code mis à jour. –

+0

A mon sens, j'utilise le xml, c'est efficace. Peut-être n'avez-vous pas ajouté 'addView (mView)' dans 'onCreate()' de l'Activity? –

+0

Pourquoi devrais-je ajouter 'addView (mView)' dans 'onCreate()'? La vue est déjà dessinée avec la méthode 'setContentView()'. J'ai seulement besoin d'une référence à la vue personnalisée, car je veux démarrer l'animation à partir de l'activité, mais cela ne semble pas fonctionner. –