2010-11-27 8 views
23

J'ai écrit un View personnalisé. Maintenant, je veux faire une petite animation personnalisée lorsque l'utilisateur la touche.Animation personnalisée dans Android

Lorsque je dis personnalisé, je veux dire que je veux essentiellement rendre chaque image moi-même, et pas utiliser une animation "prédéfinie" comme décrit here.

Quelle est la bonne façon de l'implémenter?

+0

[l'animation dans Android] (http://www.singhajit.com/android-custom-animations/) –

+0

@AjitSingh, cet article décrit les animations standards (rotation, translation, etc.). Ce que je demande à propos ici est des animations personnalisées. – aioobe

Répondre

22

plus flexible (et assez facile) façon de créer une animation personnalisée est d'étendre Animation classe.

En général:

  1. Régler la durée de votre méthode animation à l'aide setDuration().
  2. option définir la méthode interpolateur pour votre animation à l'aide setInterpolator() (pour exapmle vous pouvez utiliser LinearInterpolator ou AccelerateInterpolator etc.)
  3. Remplacer applyTransformation. Ici nous nous intéressons à la variable interpolatedTime qui change entre 0.0 et 1.0 et représente la progression de votre animation.

Voici un exemple (j'utilise cette classe pour changer ofsset de mon BitmapBitmap est lui-même tiré dans la méthode draw.): Aussi

public class SlideAnimation extends Animation { 

    private static final float SPEED = 0.5f; 

    private float mStart; 
    private float mEnd; 

    public SlideAnimation(float fromX, float toX) { 
     mStart = fromX; 
     mEnd = toX; 

     setInterpolator(new LinearInterpolator()); 

     float duration = Math.abs(mEnd - mStart)/SPEED; 
     setDuration((long) duration); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     super.applyTransformation(interpolatedTime, t); 

     float offset = (mEnd - mStart) * interpolatedTime + mStart; 
     mOffset = (int) offset; 
     postInvalidate(); 
    } 

} 

vous pouvez modifier View en utilisant Transformation#getMatrix().

MISE À JOUR

En cas si vous utilisez Android cadre Animator (ou la mise en œuvre de compatibilité - NineOldAndroids) vous pouvez simplement déclarer setter et getter pour votre propriété personnalisée View et animer directement. Voici un autre exemple:

public class MyView extends View { 

    private int propertyName = 50; 

    /* your code */ 

    public int getPropertyName() { 
     return propertyName; 
    } 

    public void setPropertyName(int propertyName) { 
     this.propertyName = propertyName; 
    } 

    /* 
    There is no need to declare method for your animation, you 
    can, of course, freely do it outside of this class. I'm including code 
    here just for simplicity of answer. 
    */ 
    public void animateProperty() { 
     ObjectAnimator.ofInt(this, "propertyName", 123).start(); 
    } 

} 
+1

Une de ces réponses avec le "Ahaaaa!" effet. Agréable! – Terry

-1

Outre la définition d'animations interpolées en XML, vous pouvez également définir des animations image par image (stockées dans res/drawable).

<animation-list 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:oneshot="true" 
> 
    <item android:drawable="@drawable/frame1" android:duration="300" /> 
    <item android:drawable="@drawable/frame2" android:duration="300" /> 
    <item android:drawable="@drawable/frame3" android:duration="300" /> 
</animation-list> 

Définissez l'animation en tant qu'arrière-plan View via setBackgroundResource.

Si vous cherchez à faire quelque chose de plus compliqué, jetez un oeil à la classe Canvas. Voir la brève intro sur comment draw with Canvas.

+1

Il veut afficher chaque image dans le programme. – dacwe

+0

Hmmm ... l'animation dépend de l'endroit où le composant a été pressé ... – aioobe

2
Animation animation = new AnimationDrawable(); 
animation.addFrame(getResources().getDrawable(R.drawable.exp1), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp2), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp3), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp4), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp5), 50); 
animation.addFrame(getResources().getDrawable(R.drawable.exp6), 50); 

Ceci est le code que j'utilise pour produire une animation personnalisée, image par image, dans mon onCreate(). Après cela, j'ai besoin de démarrer l'animation, mais je dois le faire dans le thread de l'interface utilisateur. Par conséquent, je fais usage de Runnable.

class Starter implements Runnable { 
    public void run() { 
     animation.stop(); 
     animation.start(); 
    } 
} 

je commence que Exécutable à partir d'un onClick() en utilisant la méthode .post() de ImageView:

((ImageView) findViewById(R.id.ImageToAnimateOnClicking)).post(new Starter()); 
+0

Ça a l'air sympa. Est-il faisable de rendre ces tirages programmatiques? (L'animation dépend de l'endroit où l'utilisateur clique ...) – aioobe

+0

L'animation 'AnimationDrawable' peut être définie comme View View via setBackgroundResource. Vous pouvez également trouver des moyens faciles de le positionner absolument avec des superpositions. dépend probablement de l'endroit où l'utilisateur clique! (sur un bouton? une vue de surface? une image? une liste?) –

1

Je suppose la création de chaque trame sous forme de bitmap, et passer ensuite à l'animation directement, au lieu d'obtenir le Drawable à partir de la ressource.

Bitmap bm = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_888); 
Canvas c = new Canvas(bm); 
.... Draw to bitmap 
animation.addFrame(bm,50) 
.... repeat for all frames you wish to add. 
+0

C'est dommage que je ne puisse pas dire à l'avance le nombre de FPS que le périphérique peut gérer. Si elle ne peut gérer que 5 FPS, alors je ne devrais pas dépenser autant de ressources sur le rendu d'une animation 20 FPS ... S'il y a une bonne façon de "repeter" a repeindre une repaint, et de rendre le frame sur demande, je wouldn pas avoir ce problème. – aioobe

+1

Eh bien, si vous avez utilisé Opengl, ils devraient tous être capables de gérer 30fps sans problème. Et vous devriez l'être si vous faites quelque chose de difficile graphiquement. Il y a une énorme différence de performance entre Canvas et GL. – HaMMeReD

0

Il existe quatre types d'animation que vous pouvez ajouter à votre vue personnalisée.

  1. alpha - animer la transparence de l'élément
  2. traduire - Position animer l'élément
  3. échelle - taille animer l'élément
  4. rotation - animer la rotation de l'élément

Voici une blog post qui explique chacun d'eux en détail. Une fois que vous avez terminé de créer une animation, utilisez le code ci-dessous pour ajouter cette animation personnalisée à la vue.

findById(R.id.element).startAnimation(AnimationUtils.loadAnimation(this, R.anim.custom_animation)); 
+0

Je pense que vous avez manqué le deuxième paragraphe de ma question. – aioobe