Анимация изменение цвета фона вида на Android
Как вы анимируете изменение цвета фона представления на Android?
например:
У меня есть вид с красным цветом фона. Цвет фона представления изменяется на синий. Как я могу сделать плавный переход между цветами?
Если это не может быть сделано с видом, альтернатива будет приветствоваться.
12 ответов:
Я в конечном итоге выяснить (очень хорошее) решение этой проблемы!
можно использовать TransitionDrawable для достижения этой цели. Например, в XML-файле в папке drawable вы можете написать что-то вроде:
<?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>тогда в вашем XML для фактического представления вы бы ссылались на этот TransitionDrawable в .
на этом этапе вы можете инициировать переход в своем коде по команде делать:
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground(); transition.startTransition(transitionTime);или выполнить переход в обратном порядке, вызвав:
transition.reverseTransition(transitionTime);
посмотреть Роман для другого решения с использованием API анимации свойств, который не был доступен в то время, когда этот ответ был первоначально опубликован.
вы можете использовать новый Свойство Анимации Api цвета анимация:
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();Для обратной совместимости с Android 2.X использование девять старых андроидов библиотека от Джейка Уортон.
The
getColorметод был устаревшим в Android M, поэтому у вас есть два варианта:
если вы используете библиотеку поддержки, вам нужно заменить
getColorзвонки с:ContextCompat.getColor(this, R.color.red);если вы не используете библиотека поддержки, вам нужно заменить
getColorзвонки с:getColor(R.color.red);
в зависимости от того, как ваш взгляд получает свой цвет фона и как вы получаете свой целевой цвет есть несколько различных способов сделать это.
первые два использует Android Свойство Анимации основы.
использовать Объект Аниматор если:
- ваш вид имеет свой цвет фона, определенный как
argbзначение в xml-файле.- ваш взгляд ранее имел свой цвет установленный мимо
view.setBackgroundColor()- ваш вид имеет свой цвет фона, определенный в drawable that НЕ определяет любые дополнительные свойства, такие как штрихи или угловые радиусы.
- ваш вид имеет свой цвет фона, определенный в drawable, и вы хотите удалить любые дополнительные свойства, такие как штрихи или угловые радиусы, имейте в виду, что удаление дополнительных свойств не будет анимировано.
объект аниматор работает по вызову
view.setBackgroundColorкоторый заменяет определено drawable если это не экземплярColorDrawable, что редко бывает. Это означает, что любые дополнительные свойства фона из рисунков, таких как инсульт или углы будут удалены.использовать Аниматор Значение если:
- ваш вид имеет свой цвет фона, определенный в drawable, который также устанавливает свойства, такие как штрихи или угловые радиусы, и вы хотите изменить его на новый цвет, который определяется во время работы.
использовать a переход drawable если:
- ваш вид должен переключаться между двумя drawable, которые были определены перед развертыванием.
у меня были некоторые проблемы с производительностью с переходными чертежами, которые запускаются, когда я открываю DrawerLayout, который я не смог решить, поэтому, если вы столкнетесь с каким-либо неожиданным заиканием, Вы можете столкнуться с той же ошибкой, что и я.
вам придется изменить пример аниматора значений, если вы хотите использовать StateLists drawable или LayerLists drawable, в противном случае он рухнет на
final GradientDrawable background = (GradientDrawable) view.getBackground();линии.посмотреть определение:
<View android:background="#FFFF0000" android:layout_width="50dp" android:layout_height="50dp"/>создать и использовать
ObjectAnimatorтакой.final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view, "backgroundColor", new ArgbEvaluator(), 0xFFFFFFFF, 0xff78c5f9); backgroundColorAnimator.setDuration(300); backgroundColorAnimator.start();вы также можете загрузить определение анимации из xml с помощью AnimatorInflater, как XMight делает в Android objectAnimator animate фон макета
посмотреть определение:
<View android:background="@drawable/example" android:layout_width="50dp" android:layout_height="50dp"/>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>создать и использовать ValueAnimator, как это:
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();посмотреть определение:
<View android:background="@drawable/example" android:layout_width="50dp" android:layout_height="50dp"/>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>используйте TransitionDrawable как это:
final TransitionDrawable background = (TransitionDrawable) view.getBackground(); background.startTransition(300);вы можете изменить анимацию, вызвав
.reverse()на экземпляре анимации.есть несколько других способов сделать анимацию, но эти три, пожалуй, самая распространенная. Я обычно использую ValueAnimator.
вы можете сделать аниматор объект. Например, у меня есть targetView, и я хочу изменить цвет фона:
int colorFrom = Color.RED; int colorTo = Color.GREEN; int duration = 1000; ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo) .setDuration(duration) .start();
Если вы хотите цветную анимацию, как это,
этот код поможет вам:
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();
еще один простой способ добиться этого-выполнить затухание с помощью AlphaAnimation.
- сделайте свой вид ViewGroup
- добавьте к нему дочернее представление с индексом 0, с размерами макета match_parent
- дайте вашему ребенку тот же фон, что и контейнер
- изменить фон контейнера на целевой цвет
- исчезают ребенка с помощью AlphaAnimation.
- удалить ребенка после завершения анимации (с помощью AnimationListener)
Это метод, который я использую в базовой деятельности для изменения фона. Я использую GradientDrawables, созданные в коде, но могут быть адаптированы к этому.
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); } } }обновление: в случае, если кто-то работает в той же проблеме я нашел, по какой-то причине на Android setCrossFadeEnabled(true) вызвать нежелательный эффект белого, поэтому мне пришлось переключиться на сплошной цвет для
лучший способ использовать ValueAnimator и 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();
вот хорошая функция, которая позволяет это:
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(); }
ответ дается во многих отношениях. Вы также можете использовать
ofArgb(startColor,endColor)ofValueAnimator.для 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();
я обнаружил, что реализация используется
ArgbEvaluatorв исходном коде Android лучше всего работает при переходе цветов. При использовании HSV, в зависимости от двух цветов, переход прыгал через слишком много оттенков для меня. Но этот метод не делает.если вы пытаетесь просто анимировать, используйте
ArgbEvaluatorСValueAnimatorкак предложил здесь: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();однако, если вы похожи на меня и хотите связать свой переход с каким-либо жестом пользователя или другим значение, переданное от входа,
ValueAnimatorне очень помогает (если вы не нацелены на API 22 и выше, в этом случае вы можете использоватьValueAnimator.setCurrentFraction()метод). При таргетинге ниже API 22, оберните код, найденный вArgbEvaluatorисходный код в вашем собственном методе, как показано ниже: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)))); }и использовать его, как вы хотите.
добавить папку аниматор на res. (имя должно быть аниматор). Добавьте файл ресурсов аниматора. Например res / аниматор / исчезают.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>внутри Java-файла активности, назовите это
View v = getWindow().getDecorView().findViewById(android.R.id.content); AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade); set.setTarget(v); set.start();

Comments