Текстовая цветная анимация

Есть ли способ анимировать изменение цвета текста (от anycolor до белого)?

Единственный вариант, который я придумал, размещает два текстовых изображения (с одним и тем же текстом) в одном месте и угасает верхнюю, поэтому нижний (имеющий белый цвет) станет видимым.

PS Я отказался от варианта 2 TextViews, так как он выглядел странно (края были негладкими, и, поскольку на экране было много таких элементов, это действительно зависело от прокрутки). То, что я сделал, было безумным взломом, который делает анимацию с использованием Thread и setTextColor (что также заставляет перерисовать текстовое представление).

Поскольку мне потребовалось всего 2 изменения цвета (от красного до белого и от зеленого до белого), я жестко закодировал значения и все цвета перехода между ними. Итак, вот как это выглядит:

public class BlinkingTextView extends TextView { public BlinkingTextView(Context context, AttributeSet attrs) { super(context, attrs); } public void animateBlink(final boolean red) { if (animator != null) { animator.drop(); } animator = new Animator(this, red); animator.start(); } public void clearBlinkAnimation() { if (animator != null) { animator.drop(); } } private Animator animator; private final static class Animator extends Thread { public Animator(final TextView textView, final boolean red) { this.textView = textView; if (red) { SET_TO_USE = RED; } else { SET_TO_USE = GREEN; } } private TextView textView; private final int[] SET_TO_USE; private final static int[] RED = { -2142396, -2008754, -1874854, -1740697, -1540490, -1405563, -1205099, -1004634, -804170, -669243, -469036, -334879, -200979, -67337, -1 }; private final static int[] GREEN = { -6959821, -6565826, -6106293, -5646758, -5055894, -4530309, -3939444, -3283042, -2692177, -2166592, -1575728, -1116193, -656660, -262665, -1 }; private boolean stop; @Override public void run() { int i = 0; while (i < 15) { if (stop) break; final int color = SET_TO_USE[i]; if (stop) break; textView.post(new Runnable() { @Override public void run() { if (!stop) { textView.setTextColor(color); } } }); if (stop) break; i++; if (stop) break; try { Thread.sleep(66); } catch (InterruptedException e) {} if (stop) break; } } public void drop() { stop = true; } } } 

Solutions Collecting From Web of "Текстовая цветная анимация"

Хотя я не нашел совершенно отличный метод, я попытался использовать TextSwitcher (с анимацией затухания), чтобы создать эффект изменения цвета. TextSwitcher – это вид ViewSwitcher который буквально оживляет между двумя (внутренними) TextView . Неужели вы вручную внедряете ту же систему бессознательно? 😉 Он управляет немного больше процесса для вас, поэтому вам может быть легче работать (особенно если вы хотите попробовать более привлекательные анимации). Я бы создал новый подкласс TextSwitcher и некоторые методы, например setColour() которые могут устанавливать новый цвет, а затем запускать анимацию. Затем код анимации можно перемещать за пределы основного приложения.

  • Убедитесь, что вы держите дескриптор двух TextView , которые помещаются в коммутатор
  • Изменить цвет другого TextView и вызвать setText() для анимации между ними

Если вы уже используете ViewSwitcher то я не думаю, что есть более простой способ реализовать это.

Вы можете использовать новую анимацию свойств Api для цветной анимации:

 Integer colorFrom = getResources().getColor(R.color.red); Integer colorTo = getResources().getColor(R.color.blue); ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); colorAnimation.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { textView.setTextColor((Integer)animator.getAnimatedValue()); } }); colorAnimation.start(); 

Для обратной совместимости с Android 2.x используйте библиотеку Nine Old Androids от Jake Wharton.

Самое простое решение – использовать объектные аниматоры:

 ObjectAnimator colorAnim = ObjectAnimator.ofInt(yourTextView, "textColor", Color.RED, Color.Green); colorAnim.setEvaluator(new ArgbEvaluator()); colorAnim.start(); 

Нет необходимости держать дескрипторы двух видов текста. Сначала добавьте анимацию fadeIn / fadeOut:

 textSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); textSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out)); 

тогда:

 TextView currentTextView = (TextView)(textSwitcher.getNextView().equals( textSwitcher.getChildAt(0)) ? textSwitcher.getChildAt(1) : textSwitcher.getChildAt(0) ); // setCurrentText() first to be the same as newText if you need to textSwitcher.setTextColor(fadeOutColor); ((TextView) textSwitcher.getNextView()).setTextColor(Color.WHITE); textSwitcher.setText(newText); 

Просто реализовано так, как это доказано.

Я отказался от варианта 2 TextViews, так как он выглядел странно (края были негладными, и, поскольку на экране было много таких элементов, это действительно задерживало прокрутку). То, что я сделал, было безумным взломом, который делает анимацию с использованием Thread и setTextColor (что также заставляет перерисовать текстовое представление).

Поскольку мне потребовалось всего 2 изменения цвета (от красного до белого и от зеленого до белого), я жестко закодировал значения и все цвета перехода между ними. Итак, вот как это выглядит:

 public class BlinkingTextView extends TextView { public BlinkingTextView(Context context, AttributeSet attrs) { super(context, attrs); } public void animateBlink(final boolean red) { if (animator != null) { animator.drop(); } animator = new Animator(this, red); animator.start(); } public void clearBlinkAnimation() { if (animator != null) { animator.drop(); } } private Animator animator; private final static class Animator extends Thread { public Animator(final TextView textView, final boolean red) { this.textView = textView; if (red) { SET_TO_USE = RED; } else { SET_TO_USE = GREEN; } } private TextView textView; private final int[] SET_TO_USE; private final static int[] RED = { -2142396, -2008754, -1874854, -1740697, -1540490, -1405563, -1205099, -1004634, -804170, -669243, -469036, -334879, -200979, -67337, -1 }; private final static int[] GREEN = { -6959821, -6565826, -6106293, -5646758, -5055894, -4530309, -3939444, -3283042, -2692177, -2166592, -1575728, -1116193, -656660, -262665, -1 }; private boolean stop; @Override public void run() { int i = 0; while (i < 15) { if (stop) break; final int color = SET_TO_USE[i]; if (stop) break; textView.post(new Runnable() { @Override public void run() { if (!stop) { textView.setTextColor(color); } } }); if (stop) break; i++; if (stop) break; try { Thread.sleep(66); } catch (InterruptedException e) {} if (stop) break; } } public void drop() { stop = true; } } } 

Проблема, которую я нашел с помощью valueAnimator, а также ObjectAnimator, заключается в том, что аниматор выполняет итерацию с помощью ряда случайных цветов, и переход не выглядит гладко. Я написал следующий код, который работал гладко. Надеюсь, это поможет и другому.

 public static void changeTextColor(final TextView textView, int startColor, int endColor, final long animDuration, final long animUnit){ if (textView == null) return; final int startRed = Color.red(startColor); final int startBlue = Color.blue(startColor); final int startGreen = Color.green(startColor); final int endRed = Color.red(endColor); final int endBlue = Color.blue(endColor); final int endGreen = Color.green(endColor); new CountDownTimer(animDuration, animUnit){ //animDuration is the time in ms over which to run the animation //animUnit is the time unit in ms, update color after each animUnit @Override public void onTick(long l) { int red = (int) (endRed + (l * (startRed - endRed) / animDuration)); int blue = (int) (endBlue + (l * (startBlue - endBlue) / animDuration)); int green = (int) (endGreen + (l * (startGreen - endGreen) / animDuration)); textView.setTextColor(Color.rgb(red, green, blue)); } @Override public void onFinish() { textView.setTextColor(Color.rgb(endRed, endGreen, endBlue)); } }.start(); }