2010-09-21 12 views
28

Quiero crear una imagen de progreso giratorio, y me pregunto cuál es la mejor manera de proceder. Puedo hacer que funcione con una lista de animación con, por ejemplo, 12 imágenes que cambian cada 100 ms. Esto funciona bien, pero es bastante tedioso para crear 12 imágenes o para cada tamaño y resolución:imagen giratoria. Lista de animación o rotación animada? (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" /> 

supongo que una solución más fácil es utilizar una imagen por resolución, sino más bien girarlo para cada marco. En los recursos de la plataforma (android-sdk-windows/platforms ...) encontré algo llamado animated-rotate en el archivo drawable/search_spinner.xml, pero si copio el código obtengo un error del compilador quejándose de android: framesCount y android: frameDuration (Google API 2.2 en 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" /> 

también he intentado usar una animación de rotación repetir (utilizando en la carpeta de recursos anim), pero en realidad yo prefiero el aspecto de la versión de la lista de animación.

¿Cuál es la forma recomendada de resolver este problema?

Respuesta

13

usted tiene que crear un archivo XML estirable, como a continuación:

Código:

<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

¿Por qué no está girando? –

+0

no funciona en ningún dispositivo. por favor use rotage en su lugar – vuhung3990

2

ver ejemplos aquí http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html

específicamente: Barra de progreso

  1. incremental Demuestra indicadores de progreso rotativos grandes y pequeños que se pueden incrementar o disminuir en unidades.
  2. Smooth Demuestra indicadores de progreso de rotación continua grandes y pequeños utilizados para indicar un mensaje genérico de "ocupado".
  3. Diálogos Muestra un diálogo de progreso, un cuadro de diálogo emergente que alberga una barra de progreso. Este ejemplo demuestra indicadores de progreso determinados e indeterminados.
  4. En la barra de título Muestra una pantalla de actividad con un indicador de progreso cargado configurando la función de indicador de progreso de WindowPolicy.
0

La solución de SACPK definitivamente funciona. Otra solución puede ser utilizar <animated-rotate> como en cuestión y eliminar los atributos android:framesCount="12" android:frameDuration="100" para los que el compilador se queja. Todavía funciona incluso para mi imagen de 8 cuadros.

Sin embargo, yo no te has descubierto la manera de controlar la velocidad de la animación :(.

55

Rotate drawable sugerido por Praveen no le dará el control de la cuenta de tramas. Supongamos que se desea implementar un cargador personalizada la cual consta de 8 secciones:

gif_icon

Usando animation-list enfoque, es necesario crear 8 fotogramas giradas por 45*frameNumber grados manualmente.Como alternativa, puede utilizar primero el marco y establecer la animación de rotación a la misma:

progress_icon

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

Archivo MainActivity.java

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

Esto le dará una animación suave en lugar de 8 pasos. Para solucionar este problema tenemos que aplicar interpolador de encargo:

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

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

También puede crear un widget personalizado:

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

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

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

Archivo res/anim/progress_anim.xml: enumerados anteriormente

+0

genial, muchas gracias –

+3

"gracias!", "¡yo también!", – Cephron

+0

No puedo ocultar la vista de progreso usando 'android: visibility =" invisible "' ¿alguna razón? – Prateek

6

encontré la respuesta de vokilam a ser el mejor para crear una bonita animación intensificado/escalonada. Fui a su sugerencia final e hice un widget personalizado, el único problema que encontré fue que la configuración de visibilidad no funcionaría porque estaba animada y por lo tanto siempre sería visible ...

Ajusté su código (ProgressView.java el cual retitulé StaggeredProgress.java) así:

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

} 


} 

esta configuración de la vista comienza visión en una dirección y se detiene la animación como sea necesario ... Muchas gracias de nuevo a vokilam!

Cuestiones relacionadas