fondo - paleta de colores android studio




Animar el cambio de color de fondo de vista en Android (8)

¿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.


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

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.


Este es el método que utilizo en una Actividad Base para cambiar el fondo. Estoy usando GradientDrawables generados en código, pero podría adaptarse para adaptarse.

    protected void setPageBackground(View root, int type){
        if (root!=null) {
            Drawable currentBG = root.getBackground();
            //add your own logic here to determine the newBG 
            Drawable newBG = Utils.createGradientDrawable(type); 
            if (currentBG==null) {
                if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN){
                    root.setBackgroundDrawable(newBG);
                }else{
                    root.setBackground(newBG);
                }
            }else{
                TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{currentBG, newBG});
                transitionDrawable.setCrossFadeEnabled(true);
                if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN){
                     root.setBackgroundDrawable(transitionDrawable);
                }else{
                    root.setBackground(transitionDrawable);
                }
                transitionDrawable.startTransition(400);
            }
        }
    }

actualización: en caso de que alguien se encuentre con el mismo problema que encontré, por algún motivo, en Android <4.3 usando setCrossFadeEnabled(true) un efecto de setCrossFadeEnabled(true) indeseable, por lo que tuve que cambiar a un color sólido por <4.3 usando el método @Antan Minorok ValueAnimator. encima.


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

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

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