2010-09-21 10 views
28

Je souhaite créer une image de progression rotative et je me demande quelle est la meilleure façon de procéder. Je peux le faire fonctionner avec une liste d'animation avec par exemple 12 images changeant toutes les 100ms. Cela fonctionne très bien, mais il est assez fastidieux de créer 12 images ou pour toutes les tailles et résolution:Rotation de l'image. Liste d'animation ou animée pivoter? (Android)

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> 
<item android:drawable="@drawable/ic_loading_grey_on_black_01" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_02" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_03" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_04" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_05" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_06" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_07" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_08" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_09" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_10" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_11" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_12" android:duration="100" /> 

Je suppose qu'une solution plus facile est d'utiliser une image par résolution, mais faites-le pivoter pour chaque Cadre. Dans les ressources de la plate-forme (android-sdk-windows/plates-formes ...) j'ai trouvé quelque chose appelé animated-rotate dans le fichier drawable/search_spinner.xml, mais si je copie le code obtenir une erreur de compilation se plaignant de android: framesCount and android: frameDuration (Google API 2.2 dans Eclipse):

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" 
android:drawable="@drawable/spinner_black_20" 
android:pivotX="50%" 
android:pivotY="50%" 
android:framesCount="12" 
android:frameDuration="100" /> 

J'ai aussi essayé d'utiliser une rotation animation répétée (en utilisant dans le dossier des ressources anim), mais je préfère le look de la version de la liste d'animation.

Quelle est la méthode recommandée pour résoudre ce problème?

Répondre

13

Vous devez créer un fichier xml drawable comme ci-dessous:

Code:

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" 
android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0" 
android:toDegrees="360" android:drawable="@drawable/imagefile_to_rotate" /> 
+2

Comment se fait-il qu'il ne tourne pas? –

+0

il ne fonctionne pas sur certains appareils. s'il vous plaît utiliser le rotage à la place – vuhung3990

2

voir des exemples ici http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html

spécifiquement: Progress Bar

  1. incrémental Démontre les indicateurs de progression rotatifs, grands et petits, qui peuvent être incrémentés ou décrémentés en unités.
  2. Lisse Fait la démonstration de petits et grands indicateurs de progression en rotation continue utilisés pour indiquer un message générique «occupé».
  3. Dialogues Affiche un ProgressDialog, une boîte de dialogue contextuelle qui héberge une barre de progression. Cet exemple démontre à la fois des indicateurs de progrès déterminés et indéterminés.
  4. Dans la barre de titre Fait la démonstration d'un écran d'activité avec un indicateur de progression chargé en définissant la fonction indicateur de progression de WindowPolicy.
0

La solution de SACPK fonctionne définitivement. Une autre solution peut être d'utiliser <animated-rotate> exactement comme en question et de supprimer android:framesCount="12" android:frameDuration="100" attributs pour ceux que le compilateur se plaint. Cela fonctionne même pour mon image 8 images.

Cependant, je havn't compris comment contrôler la vitesse de l'animation :(.

55

Rotate drawable suggéré par Praveen ne vous permettre de contrôler de nombre d'images. Supposons que vous souhaitez implémenter un chargeur sur mesure qui se compose de 8 sections:

gif_icon

en utilisant animation-list approche, vous devez créer 8 images pivotées par 45*frameNumber degrés manuellement.Vous pouvez également utiliser le 1er cadre et l'animation de rotation réglée sur elle:

progress_icon

fichier res/anim/progress_anim.xml:

<?xml version="1.0" encoding="utf-8"?> 
<rotate 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fromDegrees="0" 
    android:toDegrees="360" 
    android:pivotX="50%" 
    android:pivotY="50%" 
    android:repeatCount="infinite" /> 

Fichier MainActivity.java

Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); 
a.setDuration(1000); 
imageView.startAnimation(a); 

Cela vous donnera une animation fluide au lieu de 8-step. Pour corriger cela, nous devons mettre en œuvre interpolateur personnalisée:

a.setInterpolator(new Interpolator() { 
    private final int frameCount = 8; 

    @Override 
    public float getInterpolation(float input) { 
     return (float)Math.floor(input*frameCount)/frameCount; 
    } 
}); 

vous pouvez également créer un widget personnalisé:

fichier res/values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="ProgressView"> 
     <attr name="frameCount" format="integer"/> 
     <attr name="duration" format="integer" /> 
    </declare-styleable> 
</resources> 

fichier ProgressView.java:

public class ProgressView extends ImageView { 

    public ProgressView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     setAnimation(attrs); 
    } 

    public ProgressView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setAnimation(attrs); 
    } 

    public ProgressView(Context context) { 
     super(context); 
    } 

    private void setAnimation(AttributeSet attrs) { 
     TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressView); 
     int frameCount = a.getInt(R.styleable.ProgressView_frameCount, 12); 
     int duration = a.getInt(R.styleable.ProgressView_duration, 1000); 
     a.recycle(); 

     setAnimation(frameCount, duration); 
    } 

    public void setAnimation(final int frameCount, final int duration) { 
     Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); 
     a.setDuration(duration); 
     a.setInterpolator(new Interpolator() { 

      @Override 
      public float getInterpolation(float input) { 
       return (float)Math.floor(input*frameCount)/frameCount; 
      } 
     }); 
     startAnimation(a); 
    } 
} 

Fichier activity_main.xml:

<com.example.widget.ProgressView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_progress" 
    app:frameCount="8" 
    app:duration="1000"/> 

Fichier res/anim/progress_anim.xml: ci-dessus

+0

super, merci beaucoup –

+3

"merci!", "moi aussi!", – Cephron

+0

Je ne suis pas en mesure de cacher la vue d'ensemble en utilisant 'android: visibility =" invisible "' quelle raison? – Prateek

6

J'ai trouvé la réponse de vokilam être le meilleur pour créer une belle étagé/animation décalée. Je suis allé pour sa suggestion finale et fait un widget personnalisé, le seul problème que j'ai rencontré était que la visibilité de réglage ne fonctionnerait pas car il était animé et donc toujours visible ...

J'ai ajusté son code (ProgressView.java que je renomme StaggeredProgress.java) comme ceci:

public class StaggeredProgress extends ImageView { 

private Animation staggered; 

public StaggeredProgress(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    setAnimation(attrs); 
} 

public StaggeredProgress(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    setAnimation(attrs); 
} 

public StaggeredProgress(Context context) { 
    super(context); 
} 

private void setAnimation(AttributeSet attrs) { 
    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StaggeredProgress); 
    int frameCount = a.getInt(R.styleable.StaggeredProgress_frameCount, 12); 
    int duration = a.getInt(R.styleable.StaggeredProgress_duration, 1000); 
    a.recycle(); 

    setAnimation(frameCount, duration); 
} 

public void setAnimation(final int frameCount, final int duration) { 
    Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); 
    a.setDuration(duration); 
    a.setInterpolator(new Interpolator() { 

     @Override 
     public float getInterpolation(float input) { 
      return (float)Math.floor(input*frameCount)/frameCount; 
     } 
    }); 
    staggered = a; 
    //startAnimation(a); 
} 

@Override 
public void setVisibility(int visibility) { 
    super.setVisibility(visibility); 
    if(visibility == View.VISIBLE) 
     startAnimation(staggered); 
    else 
     clearAnimation(); 

} 


} 

de cette façon, la mise en visibilité de démarrage de la vue et d'arrêter l'animation au besoin ... Merci encore à vokilam!