Animer le changement de la couleur de fond de vue sur Android

comment animer le changement de couleur de fond d'une vue sur Android?

par exemple:

j'ai une vue avec une couleur de fond rouge. La couleur de fond de la vue change en bleu. Comment faire une transition en douceur entre les couleurs?

si cela ne peut pas être fait avec des vues, une alternative sera la bienvenue.

265
demandé sur Peter Mortensen 2010-04-10 22:58:38

12 réponses

j'ai fini par trouver une (assez bonne) solution pour ce problème!

vous pouvez utiliser un TransitionDrawable pour accomplir ceci. Par exemple, dans un fichier XML dans le dossier dessinable vous pouvez écrire quelque chose comme:

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

alors, dans votre XML pour la vue actuelle, vous référeriez cette transition dans l'attribut android:background .

à ce point vous pouvez initier la transition dans votre code sur commande en faisant:

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

ou exécuter la transition En Marche arrière en appelant:

transition.reverseTransition(transitionTime);

Voir Roman de la réponse pour une autre solution à l'aide de la Propriété de l'Animation de l'API, ce qui n'était pas disponible au moment de cette réponse a été posté.

323
répondu idolize 2017-05-23 12:26:35

vous pouvez utiliser le nouveau API D'Animation de propriété pour l'animation en couleur:

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

pour rétrocompatibilité avec Android 2.x utiliser Nine Old Androids library de Jake Wharton.

la méthode getColor a été dépréciée dans Android M, donc vous avez deux choix:

  • si vous utilisez la bibliothèque de soutien, vous devez remplacer le getColor appels avec:

    ContextCompat.getColor(this, R.color.red);
    
  • si vous n'utilisez pas la bibliothèque d'assistance, vous devez remplacer les appels getColor par:

    getColor(R.color.red);
    
419
répondu Roman Minenok 2016-03-12 08:56:47

selon comment votre vue obtient sa couleur de fond et comment vous obtenez la couleur de votre cible, Il ya plusieurs façons différentes de le faire.

les deux premières utilisations du animation de propriété Android cadre.

Utiliser un Objet Animateur si:

  • votre vue a sa couleur de fond définie comme une valeur argb dans un fichier xml.
  • votre vue a déjà eu sa couleur définie par view.setBackgroundColor()
  • votre vue a sa couleur de fond définie dans un dessin que ne ne définit pas des propriétés supplémentaires comme la course ou les rayons de coin.
  • votre vue ont sa couleur de fond définie dans un tirable et vous voulez supprimer toutes les propriétés supplémentaires comme les rayons de course ou de coin, gardez à l'esprit que la suppression des propriétés supplémentaires ne sera pas animée.

L'objet de l'animateur travaille en appelant view.setBackgroundColor qui remplace le défini drawable, sauf si c'est une instance d'un ColorDrawable , c'est rarement le cas. Cela signifie que toutes les propriétés de fond supplémentaires d'un dessin comme la course ou les coins seront supprimés.

Utiliser un Valeur Animateur si:

  • votre vue a sa couleur de fond définie dans un dessin qui définit également des propriétés comme le trait ou le coin rayonne et vous voulez le changer à une nouvelle couleur qui est décidée en cours d'exécution.

Utiliser un "1519480920 de Transition" drawable si:

  • votre vue devrait basculer entre deux tiroirs qui ont été définis avant le déploiement.

j'ai eu quelques problèmes de performance avec les drawables de Transition qui fonctionne pendant que j'ouvre un DrawerLayout que je n'ai pas été capable de résoudre, donc si vous rencontrez un bégaiement inattendu vous pourriez avoir couru dans le même bug que j'ai.

vous devrez modifier l'exemple de L'animateur de valeur si vous voulez utiliser un StateLists drawable ou un LayerLists drawable , sinon il se plantera sur la ligne final GradientDrawable background = (GradientDrawable) view.getBackground(); .

Objet Animateur :

voir la définition:

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

Créer et utiliser un ObjectAnimator comme ceci.

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

vous pouvez également charger la définition de l'animation à partir d'un xml en utilisant un AnimatorInflater comme XMight does dans Android objectAnimator animate backgroundColor de Layout

Valeur Animateur :

View définition:

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

Drawable définition:

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

créer et utiliser un estimateur comme ceci:

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

"Transition drawable :

voir la définition:

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

Drawable définition:

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

utilisez la TransitionDrawable comme ceci:

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

vous pouvez inverser les animations en appelant .reverse() sur l'instance d'animation.

il y a d'autres façons de faire des animations, mais ces trois-là sont probablement les plus courantes. J'utilise généralement un ValueAnimator.

121
répondu Mattias 2017-05-23 12:10:45

vous pouvez faire un animateur objet. Par exemple, j'ai un viseur targetView et je veux changer votre couleur de fond:

int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
    .setDuration(duration)
    .start();
45
répondu ademar111190 2017-01-21 10:38:11

si vous voulez une animation Couleur comme celle-ci,

Enter image description here

ce code vous aidera:

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();
17
répondu RBK 2018-04-24 09:16:10

une autre façon facile d'y parvenir est d'effectuer un fade en utilisant AlphaAnimation.

  1. Faire de votre vision une ViewGroup
  2. ajouter une vue enfant à l'index 0, avec les dimensions de mise en page match_parent
  3. donnez à votre enfant le même arrière-plan que le contenant
  4. changement du fond du conteneur à la couleur cible
  5. Effacer L'enfant en utilisant AlphaAnimation.
  6. Retirer l'enfant lorsque l'animation est terminée (à l'aide d'un AnimationListener)
11
répondu Stephane JAIS 2012-04-26 13:08:14

C'est la méthode que j'utilise dans une activité de Base pour changer le fond. J'utilise des GradientDrawables générés en code, mais qui pourraient être adaptés.

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

mise à jour: dans le cas où quelqu'un se présente à la même question, j'ai trouvé, pour une raison quelconque sur Android <4.3 en utilisant setCrossFadeEnabled(true) causer un effet indésirable blanc out donc j'ai dû passer à une couleur solide pour <4.3 en utilisant @Roman Minenok ValueAnimator méthode mentionnée ci-dessus.

8
répondu scottyab 2014-08-01 14:29:18

best way use ValueAnimator et ColorUtils.blendARGB

 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
 valueAnimator.setDuration(325);
 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {

              float fractionAnim = (float) valueAnimator.getAnimatedValue();

              view.setColorBackground(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
                                    , Color.parseColor("#000000")
                                    , fractionAnim));
        }
});
valueAnimator.start();
6
répondu Rasoul Miri 2017-10-24 12:37:27

Voici une belle fonction qui permet ceci:

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();
}
4
répondu android developer 2014-04-30 08:30:36

la réponse est donnée de plusieurs façons. Vous pouvez également utiliser ofArgb(startColor,endColor) de ValueAnimator .

pour 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();
4
répondu Palak Darji 2018-02-03 04:06:59

j'ai trouvé que l'implémentation utilisée par ArgbEvaluator dans le code source Android fait le meilleur travail dans la transition des couleurs. En utilisant HSV, selon les deux couleurs, la transition sautait à travers trop de teintes pour moi. Mais pas celle de cette méthode.

si vous essayez de simplement animer, utilisez ArgbEvaluator avec ValueAnimator comme suggéré ici :

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

Cependant, si vous êtes comme moi et que vous souhaitez liez votre transition avec un geste de l'utilisateur ou une autre valeur passée à partir d'une entrée, le ValueAnimator n'est pas d'une grande aide (à moins que vous ne cibliez L'API 22 et plus, dans ce cas vous pouvez utiliser la méthode ValueAnimator.setCurrentFraction() ). Lorsque le ciblage est inférieur à L'API 22, enveloppez le code trouvé dans ArgbEvaluator code source dans votre propre méthode, comme suit:

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

et utilisez-le comme bon vous semble.

2
répondu fahmy 2017-05-23 12:02:48

ajouter un dossier animator dans res dossier. (le nom doit être animateur ). Ajouter un fichier de ressources d'animateur. Par exemple res/animateur/fondu.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>

à l'Intérieur de l'Activité de fichier java, appelons cela

View v = getWindow().getDecorView().findViewById(android.R.id.content);
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade);
set.setTarget(v);
set.start();
2
répondu canbax 2018-05-10 11:36:28