studio Animar el cambio de color de fondo de vista en Android




paleta de colores android studio (10)

¿Cómo animas el cambio de color de fondo de una vista en Android?

Por ejemplo:

Tengo una vista con un color de fondo rojo. El color de fondo de la vista cambia a azul. ¿Cómo puedo hacer una transición suave entre colores?

Si esto no se puede hacer con vistas, una alternativa será bienvenida.


¡Terminé descubriendo una (bastante buena) solución para este problema!

Puedes usar un TransitionDrawable para lograr esto. Por ejemplo, en un archivo XML en la carpeta dibujable podría escribir algo como:

<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
    <item android:drawable="@drawable/original_state" />
    <item android:drawable="@drawable/new_state" />
</transition>

Luego, en su XML para la Vista real, haría referencia a este TransitionDrawable en el atributo android:background .

En este punto, puede iniciar la transición en su código en el comando haciendo:

TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);

O ejecute la transición a la inversa llamando a:

transition.reverseTransition(transitionTime);

Vea la respuesta de Roman para otra solución que utiliza la API de animación de propiedades, que no estaba disponible en el momento en que se publicó originalmente esta respuesta.


Dependiendo de cómo su vista obtenga su color de fondo y de cómo obtenga el color de destino, hay varias formas diferentes de hacerlo.

Los dos primeros utilizan el marco de animación de propiedades de Android .

Utilice un animador de objetos si:

  • Su vista tiene su color de fondo definido como un valor argb en un archivo xml.
  • Su vista ha tenido previamente su conjunto de colores por view.setBackgroundColor()
  • Su vista tiene su color de fondo definido en un dibujo que NO define ninguna propiedad adicional como el trazo o los radios de esquina.
  • Su vista tiene su color de fondo definido en un dibujo y desea eliminar cualquier propiedad adicional como el trazo o los radios de esquina, tenga en cuenta que la eliminación de las propiedades adicionales no se animará.

El animador de objetos funciona al llamar a view.setBackgroundColor que reemplaza al view.setBackgroundColor definido a menos que sea una instancia de un ColorDrawable , que rara vez es. Esto significa que se eliminarán las propiedades de fondo adicionales de un trazo como un trazo o esquinas.

Utilice un animador de valores si:

  • Su vista tiene su color de fondo definido en un dibujo que también establece propiedades como el trazo o los radios de las esquinas Y desea cambiarlo a un nuevo color que se decida durante la ejecución.

Use un dibujo de transición si:

  • Su vista debe cambiar entre dos dibujables que se han definido antes del despliegue.

He tenido algunos problemas de rendimiento con los objetos transitables de Transición que se ejecutan mientras estoy abriendo un DrawerLayout que no he podido resolver, por lo que si encuentra algún tartamudeo inesperado, es posible que tenga el mismo error que yo.

Tendrá que modificar el ejemplo de Value Animator si desea usar un StateLists drawable o un LayerLists drawable , de lo contrario se bloqueará en el final GradientDrawable background = (GradientDrawable) view.getBackground(); línea.

Animador de objetos :

Ver definición:

<View
    android:background="#FFFF0000"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

Crea y usa un ObjectAnimator como este.

final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view,
                                                                       "backgroundColor",
                                                                       new ArgbEvaluator(),
                                                                       0xFFFFFFFF,
                                                                       0xff78c5f9);
backgroundColorAnimator.setDuration(300);
backgroundColorAnimator.start();

También puede cargar la definición de animación desde un xml usando un AnimatorInflater como XMight en Android objectAnimator animate backgroundColor of Layout

Animador de valores :

Ver definición:

<View
    android:background="@drawable/example"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

Definición dibujable:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF"/>
    <stroke
        android:color="#edf0f6"
        android:width="1dp"/>
    <corners android:radius="3dp"/>

</shape>

Crea y usa un ValueAnimator como este:

final ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
                                                           0xFFFFFFFF,
                                                           0xff78c5f9);

final GradientDrawable background = (GradientDrawable) view.getBackground();
currentAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(final ValueAnimator animator) {
        background.setColor((Integer) animator.getAnimatedValue());
    }

});
currentAnimation.setDuration(300);
currentAnimation.start();

Transición dibujable :

Ver definición:

<View
    android:background="@drawable/example"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

Definición dibujable:

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#FFFFFF"/>
            <stroke
                android:color="#edf0f6"
                android:width="1dp"/>
            <corners android:radius="3dp"/>
        </shape>
    </item>

    <item>
        <shape>
            <solid android:color="#78c5f9"/>
            <stroke
                android:color="#68aff4"
                android:width="1dp"/>
            <corners android:radius="3dp"/>
        </shape>
    </item>
</transition>

Usa el TransitionDrawable de esta manera:

final TransitionDrawable background = (TransitionDrawable) view.getBackground();
background.startTransition(300);

Puede revertir las animaciones llamando a .reverse() en la instancia de animación.

Hay otras formas de hacer animaciones, pero estas tres son probablemente las más comunes. Generalmente uso un ValueAnimator.


Descubrí que la implementación utilizada por ArgbEvaluator en el código fuente de Android hace el mejor trabajo en la transición de colores. Al usar HSV, dependiendo de los dos colores, la transición fue saltar a través de demasiados tonos para mí. Pero este método no lo hace.

Si está intentando simplemente animar, use ArgbEvaluator con ValueAnimator como se sugiere here :

ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        view.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

Sin embargo, si es como yo y desea vincular su transición con algún gesto de usuario u otro valor transmitido desde una entrada, el ValueAnimator no es de mucha ayuda (a menos que esté apuntando a API 22 y superior, en cuyo caso puede usar el ValueAnimator.setCurrentFraction() ). Cuando apunte por debajo de API 22, ArgbEvaluator el código que se encuentra en el código fuente de ArgbEvaluator en su propio método, como se muestra a continuación:

public static int interpolateColor(float fraction, int startValue, int endValue) {
    int startA = (startValue >> 24) & 0xff;
    int startR = (startValue >> 16) & 0xff;
    int startG = (startValue >> 8) & 0xff;
    int startB = startValue & 0xff;
    int endA = (endValue >> 24) & 0xff;
    int endR = (endValue >> 16) & 0xff;
    int endG = (endValue >> 8) & 0xff;
    int endB = endValue & 0xff;
    return ((startA + (int) (fraction * (endA - startA))) << 24) |
            ((startR + (int) (fraction * (endR - startR))) << 16) |
            ((startG + (int) (fraction * (endG - startG))) << 8) |
            ((startB + (int) (fraction * (endB - startB))));
}

Y úsalo como quieras.


Otra forma fácil de lograr esto es realizar un desvanecimiento utilizando AlphaAnimation.

  1. Haz de tu vista un ViewGroup
  2. Agregue una vista secundaria en el índice 0, con dimensiones de diseño match_parent
  3. Dale a tu hijo el mismo fondo que el recipiente
  4. Cambiar al fondo del contenedor al color objetivo.
  5. Desvanecer al niño utilizando AlphaAnimation.
  6. Retire al niño cuando la animación esté completa (usando un AnimationListener)

Puedes hacer un animador de objetos. Por ejemplo, tengo un targetView y quiero cambiar el color de fondo:

int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
    .setDuration(duration)
    .start();

Aquí hay una buena función que permite esto:

public static void animateBetweenColors(final View viewToAnimateItBackground, final int colorFrom, final int colorTo,
        final int durationInMs) {
    final ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
    colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
        ColorDrawable colorDrawable = new ColorDrawable(colorFrom);

        @Override
        public void onAnimationUpdate(final ValueAnimator animator) {
            colorDrawable.setColor((Integer) animator.getAnimatedValue());
            viewToAnimateItBackground.setBackgroundDrawable(colorDrawable);
        }
    });
    if (durationInMs >= 0)
        colorAnimation.setDuration(durationInMs);
    colorAnimation.start();
}

Puedes usar la nueva Property Animation Api para la animación en color:

int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        textView.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

Para la compatibilidad con versiones anteriores de Android 2.x, use la biblioteca Nine Old Androids de Jake Wharton.

El método getColor fue obsoleto en Android M, por lo que tiene dos opciones:

  • Si usa la biblioteca de soporte, debe reemplazar las llamadas a getColor con:

    ContextCompat.getColor(this, R.color.red);
    
  • Si no usa la biblioteca de soporte, debe reemplazar las llamadas a getColor con:

    getColor(R.color.red);
    

agregar un animador de carpeta en la carpeta res . (el nombre debe ser animador ). Agrega un archivo de recursos de animador. Por ejemplo res / animator / fade.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="backgroundColor"
        android:duration="1000"
        android:valueFrom="#000000"
        android:valueTo="#FFFFFF"
        android:startOffset="0"
        android:repeatCount="-1"
        android:repeatMode="reverse" />
</set>

Dentro de la actividad del archivo java, llama a esto.

View v = getWindow().getDecorView().findViewById(android.R.id.content);
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade);
set.setTarget(v);
set.start();

La respuesta se da de muchas maneras. También puede usar ofArgb(startColor,endColor) de ValueAnimator .

para API> 21:

int cyanColorBg = ContextCompat.getColor(this,R.color.cyan_bg);
int purpleColorBg = ContextCompat.getColor(this,R.color.purple_bg);

ValueAnimator valueAnimator = ValueAnimator.ofArgb(cyanColorBg,purpleColorBg);
        valueAnimator.setDuration(500);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
              @Override
              public void onAnimationUpdate(ValueAnimator valueAnimator) {
                   relativeLayout.setBackgroundColor((Integer)valueAnimator.getAnimatedValue());
              }
        });
        valueAnimator.start();

Si quieres una animación en color como esta,

este código te ayudará:

ValueAnimator anim = ValueAnimator.ofFloat(0, 1);   
anim.setDuration(2000);

float[] hsv;
int runColor;
int hue = 0;
hsv = new float[3]; // Transition color
hsv[1] = 1;
hsv[2] = 1;
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {

        hsv[0] = 360 * animation.getAnimatedFraction();

        runColor = Color.HSVToColor(hsv);
        yourView.setBackgroundColor(runColor);
    }
});

anim.setRepeatCount(Animation.INFINITE);

anim.start();




background-color