0

Ich habe derzeit eine benutzerdefinierte Ansicht mit einer Drawable-Ressource, die ich animieren möchte, sie von einer Position zu einer anderen zu bewegen. Ich weiß, dass es zwei Möglichkeiten gibt, PropertyAnimation zu implementieren, Sie können es tun, indem Sie ValueAnimation oder ObjectAnimation verwenden. Aber mit beiden habe ich keine Informationen in Google Docs gefunden, wie man sie mit Drawable statt View verwendet. This ist das einzige Beispiel, das ich zu meinem Problem, dass ist ähnlich gefunden, und so habe ich tryed es in meinem Code zu implementieren:Wie animiert man eine Drawable in einer benutzerdefinierten Ansicht?

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

    } 
} 

Custom

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

    } 

} 

Aber ohne Wirkung. Der Wert von newPos ändert sich ordnungsgemäß (mit Logs überprüft) und der Bildschirm wird aktualisiert (mit Oberflächenaktualisierung überprüft), aber Drawable wird nicht verschoben. Was mache ich falsch? Ich hoffe auf jede Hilfe.

+0

Haben Sie überprüft, dass 'newPos' für etwas anderes von 0 ändern? Fügen Sie einige Protokolle oder Unterbrechungspunkte hinzu und versuchen Sie es erneut, wenn Sie dies nicht getan haben. – Eselfar

Antwort

0

周恩旭 brachte mich schließlich zur Lösung. Ich war in MainActivity einen dummen Fehler machen, weil ich einen neuen Verweis auf den CustomView Schaffung wurde:

mView = new CustomView(MainActivity.this); 

und zu versuchen, die Verwendung dieses Objektverweises zu animieren. Gelöst dies durch Ersetzen von:

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

Ich versuche, Ihren Code zu starten, der CustomView, es ist effizient, es hat Animation.

Sind Sie sicher, dass Sie die Methode startAnimation ausführen?

Ich füge die startAnimation() zu der Konstruktion NoteCustomView hinzu, kann ich die Animation sehen, wenn UI fertig geladen.

Code unten, verwende ich den ic_launcher als Zeichen. Und ich füge NoteCustomView dem Layout xml der Aktivität hinzu.

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, also auf diese Weise funktioniert die Animation, aber wenn ich 'startAnimation()' von der Aktivität anrufe, funktioniert es nicht. Sehen Sie sich meinen aktualisierten Code an. –

+0

In meiner Art verwende ich die XML, es ist effizient. Vielleicht haben Sie 'addView (mView)' nicht in 'onCreate()' der Aktivität hinzugefügt? –

+0

Warum sollte ich 'addView (mView)' in 'onCreate()' hinzufügen? Die Ansicht wurde bereits mit der 'setContentView()' Methode gezeichnet. Ich brauche nur einen Verweis auf die benutzerdefinierte Ansicht, weil ich die Animation aus der Aktivität starten möchte, aber das scheint nicht zu funktionieren. –

Verwandte Themen