2010-09-21 13 views
28

Ich möchte ein rotierendes Fortschrittsbild erstellen und frage mich, was der beste Weg ist, um fortzufahren. Ich kann es mit einer Animationsliste arbeiten lassen, mit zum Beispiel 12 Bildern, die alle 100ms wechseln. Dies funktioniert gut, aber es ist ziemlich langweilig 12 Bilder zu erstellen oder für jede Größe und Auflösung:Rotierendes Bild. Animationsliste oder animierte drehen? (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" /> 

Ich nehme an, dass eine einfachere Lösung ein Bild ist pro Auflösung zu verwenden, sondern drehen Sie es für jeden Rahmen. In den Plattform-Ressourcen (android-sdk-windows/platforms ...) fand ich etwas namens animated-rotate in der Datei drawable/search_spinner.xml, aber wenn ich den Code kopiere, bekomme ich einen Compilerfehler über Android: framesCount und android: frameDuration (Google APIs 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" /> 

ich habe auch versucht, eine Wiederholung drehen Animation mit (unter Verwendung von in dem anim Ressourcenordner), aber ich eigentlich lieber das Aussehen der Animationsliste Version.

Was ist die empfohlene Lösung dieses Problems?

Antwort

13

Sie haben eine ziehbar XML-Datei wie unten zu erstellen:

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

Wie kommt es, dass es nicht rotiert? –

+0

es funktioniert nicht auf einem Gerät. Bitte verwenden Sie rotation – vuhung3990

2

siehe Beispiele hier http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html

speziell: Progress Bar

  1. Incremental Demonstriert große und kleine rotierende Fortschrittsanzeigen, die in Einheiten inkrementiert oder dekrementiert werden können.
  2. Glätten Demonstriert große und kleine kontinuierlich rotierende Fortschrittsanzeigen, die verwendet werden, um eine generische "Beschäftigt" -Nachricht anzuzeigen.
  3. Dialoge Demonstriert einen ProgressDialog, einen Popup-Dialog, der eine Fortschrittsleiste enthält. Dieses Beispiel zeigt sowohl bestimmte als auch unbestimmte Fortschrittsindikatoren.
  4. In Titelleiste Demonstriert einen Aktivitätsbildschirm mit einer Fortschrittsanzeige, die durch Festlegen der Fortschrittsanzeigefunktion der WindowPolicy geladen wird.
0

SACPKs Lösung funktioniert definitiv. Eine andere Lösung kann sein, <animated-rotate> genau wie fraglich zu verwenden und android:framesCount="12" android:frameDuration="100" Attribute für diejenigen zu entfernen, die der Compiler beschwert. Es funktioniert immer noch selbst für mein 8-Frame-Bild.

jedoch havnt ich herausgefunden, wie die Geschwindigkeit der Animation steuern :(.

55

Rotate drawable von Praveen vorgeschlagen wird nicht Sie die Kontrolle über Bildzählwertes geben. Nehmen wir an, Sie eine benutzerdefinierte loader implementieren möchten die besteht aus 8 Sektionen:

gif_icon

animation-list Ansatz verwenden, müssen Sie 8 Frames von 45*frameNumber Grad manuell gedreht erstellen.Alternativ können Sie erste Frame und setzen Rotation Animation, um es verwenden:

progress_icon

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

Datei MainActivity.java

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

Dies wird Ihnen flüssige Animationen geben statt 8 Schritte. Um dies zu beheben, müssen wir individuellen Interpolator implementieren:

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

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

Sie können auch ein eigenes Widget erstellen:

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

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

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

Datei res/anim/progress_anim.xml: oben aufgeführten

+0

super, vielen Dank –

+3

"Danke!", "Ich auch!", – Cephron

+0

Ich bin nicht in der Lage, die Fortschrittsanzeige mit 'android: Sichtbarkeit =" unsichtbar "' aus irgendeinem Grund zu verbergen? – Prateek

6

I vokilam Antwort gefunden die beste zu sein, eine schöne gestufte/gestaffelte Animation zu erstellen. Ich ging zu seinem letzten Vorschlag und machte ein benutzerdefiniertes Widget, das einzige Problem, das ich antraf, war, dass das Einstellen der Sichtbarkeit nicht funktionierte, weil es animiert war und somit immer sichtbar war ...

Ich habe seinen Code angepasst (ProgressView.java die ich umbenannt StaggeredProgress.java) wie folgt aus:

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

} 


} 

diese Weise die Auffassung der Sichtbarkeit startet und stoppt die Animation nach Bedarf ... Vielen dank nochmals Einstellung vokilam!