2011-01-11 86 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();