2010-09-21 18 views
28

Voglio creare un'immagine di avanzamento rotante e mi chiedo quale sia il modo migliore di procedere. Posso farlo funzionare con una lista di animazioni con, per esempio, 12 immagini che cambiano ogni 100ms. Questo funziona bene, ma è abbastanza noioso per creare 12 immagini o per ogni dimensione e risoluzione:Immagine rotante. Elenco di animazione o animati ruotano? (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" /> 

suppongo che una soluzione più facile è quella di utilizzare un'immagine per la risoluzione, ma piuttosto ruotarlo per ogni telaio. Nelle risorse della piattaforma (android-sdk-windows/piattaforme ...) ho trovato qualcosa chiamato rotazione animata nel file drawable/search_spinner.xml, ma se copio il codice ottieni un errore del compilatore che si lamenta di android: framesCount e android: frameDuration (Google API 2.2 in 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" /> 

inoltre ho provato utilizzando un'animazione rotazione ripetizione (utilizzando nella cartella delle risorse Anim), ma io in realtà preferisco l'aspetto della versione lista di animazione.

Qual è il modo consigliato per risolvere questo problema?

risposta

13

È necessario creare un file XML drawable come di seguito:

Codice:

<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

Come mai non ruota? –

+0

non funziona su alcuni dispositivi. per favore usa rotazione invece – vuhung3990

2

si vedano gli esempi qui http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html

specificamente: Progress Bar

  1. incrementale Dimostra gli indicatori di progresso rotanti grandi e piccoli che possono essere incrementati o decrementati in unità.
  2. Smooth Dimostra indicatori di avanzamento rotanti a rotazione continua grandi e piccoli utilizzati per indicare un messaggio generico "occupato".
  3. Finestre di dialogo Dimostrazione di una finestra di dialogo Progress, una finestra di dialogo popup che ospita una barra di avanzamento. Questo esempio dimostra sia indicatori di stato determinati che indeterminati.
  4. Nella barra del titolo Dimostra una schermata di attività con un indicatore di avanzamento caricato impostando la funzione di indicatore di avanzamento di WindowPolicy.
0

La soluzione di SACPK funziona sicuramente. Un'altra soluzione può essere quella di utilizzare <animated-rotate> proprio come in questione e rimuovere gli attributi android:framesCount="12" android:frameDuration="100" per quelli che il compilatore si lamenta. Funziona ancora anche per la mia immagine a 8 fotogrammi.

Tuttavia, ho havn't capito come controllare la velocità dell'animazione :(.

55

Rotate drawable suggerita da Praveen non vi darà il controllo del conteggio dei fotogrammi. Supponiamo che si desidera implementare un caricatore personalizzato che si compone da 8 sezioni:

gif_icon

Utilizzando animation-list approccio, è necessario creare 8 fotogrammi ruotati di 45*frameNumber gradi manualmente.In alternativa, è possibile utilizzare prima cornice e impostare l'animazione di rotazione ad esso:

progress_icon

File 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" /> 

File MainActivity.java

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

Questo vi darà animazioni fluide, invece di 8-a gradini. Per risolvere questo problema abbiamo bisogno di implementare interpolator personalizzato:

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

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

Inoltre è possibile creare un widget personalizzato:

File 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> 

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

File 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"/> 

File res/anim/progress_anim.xml: sopra elencati

+0

ottimo, grazie mille –

+3

"grazie!", "anche io!", – Cephron

+0

Non riesco a nascondere la progressview usando 'android: visibility =" invisible "' nessun motivo? – Prateek

6

Ho trovato la risposta di vokilam di essere il migliore per creare una bella animazione gradini/sfalsati. Sono andato per il suo suggerimento finale e ho creato un widget personalizzato, l'unico problema che ho riscontrato era che l'impostazione della visibilità non funzionava perché era animata e quindi sarebbe sempre visibile ...

Ho corretto il suo codice (ProgressView.java che ho rinominato StaggeredProgress.java) come questo:

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

} 


} 

questa impostazione inizia visibilità della vista strada e si ferma l'animazione come richiesto ... Molte grazie ancora a vokilam!