it-swarm.com.de

Animieren Sie die Hintergrundfarbe für die Ansichtsänderung auf Android

Wie animiert man die Änderung der Hintergrundfarbe einer Ansicht auf Android?

Zum Beispiel:

Ich habe eine Ansicht mit einer roten Hintergrundfarbe. Die Hintergrundfarbe der Ansicht ändert sich in blau. Wie kann ich einen fließenden Übergang zwischen Farben erzielen?

Wenn dies mit Ansichten nicht möglich ist, ist eine Alternative willkommen.

302
hpique

Am Ende fand ich eine (ziemlich gute) Lösung für dieses Problem!

Sie können ein TransitionDrawable verwenden, um dies zu erreichen. In einer XML-Datei im Zeichenordner könnten Sie beispielsweise Folgendes schreiben:

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

Dann würden Sie in Ihrem XML für die tatsächliche Ansicht im Attribut Android:background Auf diese TransitionDrawable verweisen.

Zu diesem Zeitpunkt können Sie den Übergang in Ihrem Code auf Befehl einleiten, indem Sie Folgendes ausführen:

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

Oder führen Sie den Übergang in umgekehrter Reihenfolge aus, indem Sie Folgendes aufrufen:

transition.reverseTransition(transitionTime);

Siehe Antwort von Roman für eine andere Lösung mit der Eigenschaftsanimations-API, die zum Zeitpunkt der Veröffentlichung dieser Antwort noch nicht verfügbar war.

349
idolize

Sie können new Property Animation Api für die Farbanimation verwenden:

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

Für die Abwärtskompatibilität mit Android 2.x) verwenden Sie Nine Old Androids library von Jake Wharton.

Die getColor -Methode war in Android M veraltet, daher haben Sie zwei Möglichkeiten:

  • Wenn Sie die Unterstützungsbibliothek verwenden, müssen Sie die getColor Aufrufe ersetzen durch:

    ContextCompat.getColor(this, R.color.red);
    
  • wenn Sie die Unterstützungsbibliothek nicht verwenden, müssen Sie die getColor -Aufrufe ersetzen durch:

    getColor(R.color.red);
    
465
Roman Minenok

Je nachdem, wie Ihre Ansicht ihre Hintergrundfarbe erhält und wie Sie Ihre Zielfarbe erhalten, gibt es verschiedene Möglichkeiten, dies zu tun.

Die ersten beiden verwenden das Android Property Animation Framework.

Verwenden Sie einen Object Animator wenn:

  • Die Hintergrundfarbe Ihrer Ansicht ist als argb Wert in einer XML-Datei definiert.
  • Die Farbe Ihrer Ansicht wurde zuvor von view.setBackgroundColor() festgelegt.
  • Die Hintergrundfarbe Ihrer Ansicht ist in einer Zeichenfunktion definiert, die KEINE zusätzlichen Eigenschaften wie Konturen oder Eckenradien definiert .
  • In Ihrer Ansicht ist die Hintergrundfarbe in einer Zeichenfläche definiert, und Sie möchten zusätzliche Eigenschaften wie Konturen oder Eckenradien entfernen. Beachten Sie jedoch, dass das Entfernen der zusätzlichen Eigenschaften nicht animiert wird.

Der Objektanimator ruft view.setBackgroundColor Auf, das die definierte Zeichenfunktion ersetzt, es sei denn, es handelt sich um eine Instanz von ColorDrawable, die es selten ist. Dies bedeutet, dass alle zusätzlichen Hintergrundeigenschaften aus einem Zeichenelement wie Strich oder Ecken entfernt werden.

Verwenden Sie einen Value Animator wenn:

  • In Ihrer Ansicht ist die Hintergrundfarbe in einer Zeichenfläche definiert, in der auch Eigenschaften wie Strich oder Eckenradius festgelegt werden, UND Sie möchten sie in eine neue Farbe ändern, die während der Ausführung festgelegt wird.

Verwenden Sie ein Transition drawable wenn:

  • Ihre Ansicht sollte zwischen zwei Zeichenelementen wechseln, die vor der Bereitstellung definiert wurden.

Ich hatte einige Leistungsprobleme mit Transition-Drawables, die ausgeführt wurden, während ich ein DrawerLayout öffne, das ich nicht lösen konnte. Wenn Sie also auf unerwartetes Ruckeln stoßen, ist möglicherweise derselbe Fehler aufgetreten wie ich.

Sie müssen das Value Animator-Beispiel ändern, wenn Sie ein StateLists drawable oder ein LayerLists drawable verwenden möchten, da es sonst in der final GradientDrawable background = (GradientDrawable) view.getBackground(); -Zeile abstürzt .

Object Animator :

Definition anzeigen:

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

Erstellen und verwenden Sie ein ObjectAnimator wie dieses.

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

Sie können die Animationsdefinition auch mit einem AnimatorInflater aus einer XML-Datei laden, wie dies XMight in Android objectAnimator animiert backgroundColor of Layout tut

Value Animator :

Definition anzeigen:

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

Zeichenbare Definition:

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

Erstellen und verwenden Sie einen ValueAnimator wie folgt:

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

Übergang zeichnbar :

Definition anzeigen:

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

Zeichenbare Definition:

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

Verwenden Sie das TransitionDrawable folgendermaßen:

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

Sie können die Animationen umkehren, indem Sie .reverse() in der Animationsinstanz aufrufen.

Es gibt einige andere Möglichkeiten, um Animationen zu erstellen, aber diese drei sind wahrscheinlich die am häufigsten verwendeten. Ich benutze in der Regel einen ValueAnimator.

127
Mattias

Sie können einen Objekt-Animator erstellen. Ich habe zum Beispiel eine targetView und möchte Ihre Hintergrundfarbe ändern:

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

Wenn Sie eine Farbanimation wie diese wünschen,

Enter image description here

dieser Code wird Ihnen helfen:

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

am besten verwenden Sie ValueAnimator und 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.setBackgroundColor(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
                                    , Color.parseColor("#000000")
                                    , fractionAnim));
        }
});
valueAnimator.start();
11
Rasoul Miri

Eine andere einfache Möglichkeit, dies zu erreichen, besteht darin, mit AlphaAnimation eine Überblendung durchzuführen.

  1. Machen Sie Ihre Ansicht zu einer ViewGroup
  2. Fügen Sie ihr am Index 0 eine untergeordnete Ansicht mit den Abmessungen match_parent hinzu
  3. Geben Sie Ihrem Kind den gleichen Hintergrund wie dem Behälter
  4. Ändern Sie den Hintergrund des Containers auf die Zielfarbe
  5. Blenden Sie das Kind mit AlphaAnimation aus.
  6. Entfernen Sie das untergeordnete Element, wenn die Animation abgeschlossen ist (mithilfe eines AnimationListener).
11
Stephane JAIS

Dies ist die Methode, die ich in einer Basisaktivität verwende, um den Hintergrund zu ändern. Ich verwende im Code generierte GradientDrawables, die aber angepasst werden könnten.

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

pdate: Falls jemand auf dasselbe Problem stößt, das ich aus irgendeinem Grund auf Android <4.3 using setCrossFadeEnabled(true) gefunden habe, kann dies zu einem unerwünschten White-Out-Effekt führen Daher musste ich mit der oben angegebenen @ Roman Minenok ValueAnimator-Methode auf eine Volltonfarbe für <4,3 umstellen.

9
scottyab

Die Antwort wird auf viele Arten gegeben. Sie können auch ofArgb(startColor,endColor) von ValueAnimator verwenden.

für 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();
5
Palak Darji

Hier ist eine nette Funktion, die dies ermöglicht:

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

füge einen Ordner animator in den res Ordner ein. (Der Name muss Animator sein.) Fügen Sie eine Animator-Ressourcendatei hinzu. Zum Beispiel 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>

Nennen Sie diese Datei in Activity Java file

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

Ich habe festgestellt, dass die Implementierung, die von ArgbEvaluator im Android= Quellcode verwendet wird, beim Übergang von Farben am besten funktioniert. Bei Verwendung von HSV war der Übergang abhängig von den beiden Farben ein Sprung durch zu viele Farben für mich, aber diese Methode tut es nicht.

Wenn Sie versuchen, einfach zu animieren, verwenden Sie ArgbEvaluator mit ValueAnimator wie vorgeschlagen hier :

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

Wenn Sie jedoch wie ich sind und Ihren Übergang mit einer Benutzergeste oder einem anderen Wert verknüpfen möchten, der von einer Eingabe übergeben wurde, ist ValueAnimator keine große Hilfe (sofern Sie nicht auf API 22 und höher abzielen) In diesem Fall können Sie die Methode ValueAnimator.setCurrentFraction() verwenden. Wenn Sie unter API 22 ausrichten, schließen Sie den in ArgbEvaluator source code enthaltenen Code wie folgt in Ihre eigene Methode ein:

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

Und benutze es wie du willst.

2
fahmy