2011-01-11 87 views
11

有没有一种方法来动画文本颜色变化(从任何颜色变为白色)?文本颜色动画

我想出的唯一变种是将两个文本视图(使用相同的文本)放在一个地方,然后淡出顶部的一个,所以底部的一个(具有白色)将变得可见。

P.S.我放弃了2个TextView的变体,因为它看起来很奇怪(边缘不平滑,因为屏幕上有很多这样的元素,所以它实际上滞后于滚动)。我做了什么,是一个疯狂的黑客,使用Thread和setTextColor(也强制重绘textview)的动画。

由于我只需要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; 
    } 
} 
} 

回答

3

虽然我还没有找到一个完全不同的方法,我试图用TextSwitcher(与动画渐变)创建色彩变化效果。 A TextSwitcher是一种ViewSwitcher,它在两个(内部)TextView之间字面上有动画效果。您是否在不知情的情况下手动实施了相同的系统? ;)它为你管理更多的过程,所以你可能会觉得更容易处理(特别是如果你想尝试更多的参与动画)。我会创建TextSwitcher的新子类和一些方法,例如setColour()它可以设置新的颜色,然后触发动画。动画代码然后可以移动到主应用程序之外。

  • 一定要保持对被放入切换
  • 改变其他TextView的颜色两个TextView个手柄,并呼吁setText()如果你已经

它们之间设置动画使用ViewSwitcher然后我不认为有一个更简单的方法来实现这一点。

+0

谢谢。我实际上并没有实现我所说的方法(只是想到了它)。非常感谢,我会尝试你的方法:) – 2011-01-11 13:47:04

3

无需保留两个文本视图的句柄。首先添加淡入/淡出动画:

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

就实现了它这样如此证明工作。

0

我放弃了2个TextViews的变体,因为它看起来很奇怪(边缘不平滑,因为屏幕上有很多这样的元素,它确实滞后于滚动)。我做了什么,是一个疯狂的黑客,使用Thread和setTextColor(也强制重绘textview)的动画。

由于我只需要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; 
    } 
} 
} 
41

您可以使用新的Property Animation 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 library从杰克沃顿向后兼容性。

17

最简单的解决方案将是使用对象的动画师:

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

这是最好的答案,谢谢 – 2016-11-17 06:59:07

0

我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(); 
} 
0

正如其他人所说,使用ObjectAnimator解决了这个问题。但是,在现有的职位 - 我没有看到如何设置持续时间。对我而言,颜色变化会立即发生。

下面示出了该解决方案:

  1. 设置与一些间隔中的动画;感谢发帖:https://plus.google.com/+CyrilMottier/posts/X4yoNHHszwq

  2. 的方式,不断往复循环的2种颜色之间


void animateTextViewColors(TextView textView, Integer colorTo) { 

    final Property<TextView, Integer> property = new Property<TextView, Integer>(int.class, "textColor") { 
     @Override 
     public Integer get(TextView object) { 
      return object.getCurrentTextColor(); 
     } 

     @Override 
     public void set(TextView object, Integer value) { 
      object.setTextColor(value); 
     } 
    }; 

    final ObjectAnimator animator = ObjectAnimator.ofInt(textView, property, colorTo); 
    animator.setDuration(8533L); 
    animator.setEvaluator(new ArgbEvaluator()); 
    animator.setInterpolator(new DecelerateInterpolator(2)); 
    animator.start(); 
} 

void oscillateDemo(final TextView textView) { 

    final int whiteColor = ContextCompat.getColor(TheApp.getAppContext(), R.color.white); 
    final int yellowColor = ContextCompat.getColor(TheApp.getAppContext(), R.color.yellow); 

    final int counter = 100; 

    Thread oscillateThread = new Thread() { 
     @Override 
     public void run() { 

      for (int i = 0; i < counter; i++) { 

       final int fadeToColor = (i % 2 == 0) 
         ? yellowColor 
         : whiteColor; 

       getActivity().runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 

         animateTextViewColors(textView, fadeToColor); 
        } 
       });          

       try { 
        Thread.sleep(2450); 
       } 
       catch (InterruptedException iEx) {} 
      } 
     } 
    }; 

    oscillateThread.start(); 
} 
1

最佳方式使用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(); 

       textView.setTextColor(ColorUtils.blendARGB(Color.parseColor("#FFFFFF") 
            , Color.parseColor("#000000") 
            , fractionAnim)); 
     } 
}); 
valueAnimator.start();