Animacja zmiany koloru tła widoku na Androidzie
Jak animować zmianę koloru tła widoku na Androidzie?
Na przykład:
Mam widok z czerwonym kolorem tła. Kolor tła widoku zmienia się na niebieski. Jak zrobić płynne przejście między kolorami?
Jeśli nie można tego zrobić z widokami, alternatywa będzie mile widziana.
12 answers
Znalazłem (całkiem dobre) rozwiązanie tego problemu!
Możesz użyć TransitionDrawable aby to osiągnąć. Na przykład, w pliku XML w folderze drawable możesz napisać coś w stylu:
<?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>
Następnie, w Twoim XML dla rzeczywistego widoku będziesz odwoływać się do tego przejścia w atrybucie android:background
.
W tym momencie możesz zainicjować Przejście W swoim kodzie na polecenie wykonując:
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);
Lub uruchomić Przejście W odwrotnej kolejności przez wywołanie:
transition.reverseTransition(transitionTime);
Zobacz Roman ' s answer dla innego rozwiązania wykorzystującego API animacji właściwości, które nie było dostępne w momencie, gdy odpowiedź została pierwotnie opublikowana.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:35
Możesz użyć nowego API animacji właściwości do kolorowej animacji:
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();
Dla wstecznej kompatybilności z Androidem 2.x Użyj dziewięciu starych bibliotek androidów od Jake ' a Whartona.
Metoda getColor
została przestarzała w Androidzie m, więc masz dwa wyjścia:
-
Jeśli używasz biblioteki wsparcia, musisz zastąpić
getColor
wywołania przez:ContextCompat.getColor(this, R.color.red);
-
Jeśli nie używasz biblioteki wsparcia, musisz zastąpić wywołania
getColor
z:getColor(R.color.red);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-12 08:56:47
W zależności od tego, jak widok otrzymuje swój kolor tła i jak uzyskać kolor docelowy, istnieje kilka różnych sposobów, aby to zrobić.
Pierwsze dwa wykorzystują framework Android Property Animation .
Użyj animatora obiektu jeśli:
- twój Widok ma kolor tła zdefiniowany jako wartość
argb
w pliku xml. - Twój widok miał wcześniej ustawiony kolor przez
view.setBackgroundColor()
- twój Widok ma kolor tła zdefiniowany w drawable, który nie definiuje żadnych dodatkowych właściwości, takich jak promienie obrysu lub rogu.
- twój Widok ma kolor tła zdefiniowany w drawable i chcesz usunąć dodatkowe właściwości, takie jak promienie obrysu lub rogu, pamiętaj, że usunięcie dodatkowych właściwości nie będzie animowane.
Animator obiektu działa poprzez wywołanie view.setBackgroundColor
, które zastępuje zdefiniowany drawable, chyba że jest to instancja ColorDrawable
, którą rzadko jest. Oznacza to, że każdy dodatkowe właściwości tła z rysowalnego obrysu lub narożników zostaną usunięte.
Użyj animatora wartości jeśli:
- twój Widok ma kolor tła zdefiniowany w drawable, który również ustawia właściwości, takie jak promienie obrysu lub rogu i chcesz zmienić go na nowy kolor, który jest ustalany podczas pracy.
Użyj przejścia drawable jeśli:
- Twój widok powinien przełączyć się między dwoma rysowalnymi, które zostały zdefiniowane przed rozmieszczeniem.
Miałem pewne problemy z wydajnością z przejściówkami, które działają podczas otwierania szuflady, której nie byłem w stanie rozwiązać, więc jeśli napotkasz jakieś nieoczekiwane jąkanie, możesz napotkać ten sam błąd, co ja.
Będziesz musiał zmodyfikować przykład animatora wartości, jeśli chcesz użyć StateLists drawable lub LayerLists drawable , w przeciwnym razie zostanie on zawieszony na linii final GradientDrawable background = (GradientDrawable) view.getBackground();
.
Definicja widoku:
<View
android:background="#FFFF0000"
android:layout_width="50dp"
android:layout_height="50dp"/>
Utwórz i użyj ObjectAnimator
w ten sposób.
final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view,
"backgroundColor",
new ArgbEvaluator(),
0xFFFFFFFF,
0xff78c5f9);
backgroundColorAnimator.setDuration(300);
backgroundColorAnimator.start();
Można również wczytać definicję animacji z xml za pomocą AnimatorInflater, tak jak robi to XMight w Android objectAnimator animate backgroundColor układu
Definicja widoku:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
Definicja Drawable:
<?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>
Tworzenie i używanie ValueAnimator jak to:
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();
Definicja widoku:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
Definicja Drawable:
<?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>
Użyj przejścia w ten sposób:
final TransitionDrawable background = (TransitionDrawable) view.getBackground();
background.startTransition(300);
Animacje można odwrócić, wywołując .reverse()
na wystąpieniu animacji.
Istnieje kilka innych sposobów tworzenia animacji, ale te trzy są prawdopodobnie najczęstsze. Zazwyczaj używam ValueAnimator.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:45
Możesz utworzyć animator obiektów. Na przykład mam targetView i chcę zmienić kolor tła:
int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
.setDuration(duration)
.start();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-21 10:38:11
Jeśli chcesz mieć taką kolorową animację,
Ten kod ci pomoże:
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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-24 09:16:10
Innym łatwym sposobem, aby to osiągnąć, jest wykonanie zaniku przy użyciu AlphaAnimation.
- Make your view a ViewGroup
- Dodaj do niego widok potomny w indeksie 0, z wymiarami układu match_parent
- nadaj dziecku takie samo tło jak pojemnik
- Zmiana tła kontenera na kolor docelowy
- Usuń dziecko za pomocą AlphaAnimation.
- Usuń dziecko po zakończeniu animacji (za pomocą AnimationListener)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-26 13:08:14
Jest to metoda, której używam w podstawowej aktywności do zmiany tła. Używam GradientDrawables wygenerowanych w kodzie, ale można je dostosować do własnych potrzeb.
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);
}
}
}
Update: W przypadku, gdy ktoś uruchomi ten sam problem, który znalazłem, z jakiegoś powodu na Androidzie setCrossFadeEnabled(true) spowodować niepożądany biały efekt, więc musiałem przełączyć się na jednolity kolor dla
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-01 14:29:18
Najlepszy sposób użycia ValueAnimator i 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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 12:37:27
Oto Ładna funkcja, która na to pozwala:
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();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-30 08:30:36
Odpowiedź jest udzielana na wiele sposobów. Możesz również użyć ofArgb(startColor,endColor)
z ValueAnimator
.
Dla 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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-03 04:06:59
Odkryłem, że implementacja używana przez ArgbEvaluator
w kodzie źródłowym Androida najlepiej sprawdza się przy przechodzeniu kolorów. Przy użyciu HSV, w zależności od dwóch kolorów, Przejście przeskakiwało zbyt wiele odcieni dla mnie. Ale ta metoda Nie.
Jeśli próbujesz po prostu animować, użyj ArgbEvaluator
z ValueAnimator
zgodnie z sugestią tutaj:
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();
Jeśli jednak jesteś taki jak ja i chcesz powiązać swoje przejście z jakimś gestem użytkownika lub inną wartością przekazaną z wejścia, ValueAnimator
nie jest zbyt pomocne (chyba że kierujesz się na API 22 i wyżej, w takim przypadku możesz użyć ValueAnimator.setCurrentFraction()
metoda). Przy kierowaniu poniżej API 22, zawiń kod znaleziony w ArgbEvaluator
Kod źródłowy w Twojej własnej metodzie, jak pokazano poniżej:
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))));
}
I używaj go jak chcesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:48
Dodaj folder animator do folderu res . (nazwa musi być animator ). Dodaj plik zasobów programu animator. Na przykład 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>
Wewnątrz Activity java file, call this
View v = getWindow().getDecorView().findViewById(android.R.id.content);
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade);
set.setTarget(v);
set.start();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-10 11:36:28