2011-01-11 8 views
11

Gibt es eine Möglichkeit, eine Textfarbe zu ändern (von Anycolor zu Weiß)?Text Farbanimation

Die einzige Variante, die ich erfunden habe, ist das Platzieren von zwei Textansichten (mit demselben Text) an einer Stelle und das Ausblenden der oberen, so dass die untere (die eine weiße Farbe hat) sichtbar wird.

P.S. Ich habe die Variante der 2 TextViews verschrottet, da sie seltsam aussah (die Kanten waren nicht glatt und, da ich viele solcher Elemente auf dem Bildschirm habe, lag das Scrollen wirklich hinterher). Was ich getan habe, war ein verrückter Hack, der die Animation mit der Verwendung eines Threads und setTextColor ausführt (was auch das Neuzeichnen einer Textansicht erzwingt).

Da ich nur 2 Farbänderungen brauchte (von rot nach weiß und von grün nach weiß) habe ich die Werte und alle Übergangsfarben zwischen ihnen fest programmiert. Also hier ist, wie es aussieht:

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

Antwort

3

Obwohl ich nicht ein völlig unterschiedlichen Verfahren gefunden habe, hat ich versucht, ein TextSwitcher (mit der Fade-Animation) zu verwenden, um den Farbwechseleffekt zu erzeugen. Eine TextSwitcher ist eine Art von ViewSwitcher, die buchstäblich zwischen zwei (internen) TextView s animiert. Haben Sie das gleiche System unwissentlich manuell implementiert? ;) Es verwaltet ein bisschen mehr von dem Prozess für Sie, so dass Sie es leichter finden können, damit zu arbeiten (besonders wenn Sie mehr beteiligte Animationen ausprobieren möchten). Ich würde eine neue Unterklasse von TextSwitcher und einige Verfahren, z. setColour() kann die neue Farbe festlegen und dann eine Animation auslösen. Der Animationscode kann dann außerhalb Ihrer Hauptanwendung verschoben werden.

  • stellen Sie sicher an den beiden TextView s einen Griff zu halten, die
  • Änderung der Farbe der anderen TextView und rufen setText() in den Umschalter zwischen ihnen gestellt werden

zu animieren, wenn Sie bereits mit einem ViewSwitcher dann glaube ich nicht, es gibt eine einfachere Möglichkeit, dies zu implementieren.

+0

Dank . Ich habe die Methode, über die ich gesprochen habe, nicht implementiert (nur darüber nachgedacht). Vielen Dank, ich werde Ihre Methode jetzt versuchen :) –

3

Keine Notwendigkeit, Griffe zu den zwei Textansichten zu behalten. Zuerst fügen Sie die fadeIn/fadeOut Animationen:

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

dann:

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

einfach es so implementiert, so bewiesen zu arbeiten.

0

Ich verwarf die Variante der 2 TextViews, da es seltsam aussah (Kanten waren nicht glatt und, da ich viele solcher Elemente auf dem Bildschirm habe, war es wirklich dem Scrollen nachgelagert). Was ich getan habe, war ein verrückter Hack, der die Animation mit der Verwendung eines Threads und setTextColor ausführt (was auch das Neuzeichnen einer Textansicht erzwingt).

Da ich nur 2 Farbänderungen brauchte (von rot nach weiß und von grün nach weiß) habe ich die Werte und alle Übergangsfarben zwischen ihnen fest programmiert. Also hier ist, wie es aussieht:

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

Sie neue Property Animation Api für Farbanimation verwenden:

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

Für Rückwärtskompatibilität mit Android 2.x Verwendung Nine Old Androids library von Jake Wharton.

17

Die einfachste Lösung wird Object Animator zu verwenden:

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

Dies ist die beste Antwort, danke –

+0

wie die Geschwindigkeit des Objektanimator steuern? – pollaris

0

Die Frage, die ich auch mit valueAnimator gefunden als ObjectAnimator ist, dass die Animation durchläuft eine Reihe von zufälligen Farben und dem Übergang nicht sieht glatt. Ich schrieb den folgenden Code, der reibungslos funktionierte. Hoffe es hilft auch anderen.

0

Wie andere erwähnen, löst ObjectAnimator dafür. In den bestehenden Posts sah ich jedoch nicht, wie man die Dauer festlegte. Bei mir würde der Farbwechsel sofort passieren.

Die Lösung unten zeigt:

  1. die Animation mit einem Intervall einstellen; Dank schreiben: https://plus.google.com/+CyrilMottier/posts/X4yoNHHszwq

  2. einen Weg zur kontinuierlichen Zyklus hin und her zwischen den zwei Farben


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

beste Art und Weise verwendet ValueAnimator und 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();