2011-01-11 38 views
11

C'è un modo per animare un cambio di colore del testo (da anycolor a bianco)?Animazione del colore del testo

L'unica variante che mi è venuta in mente, consiste nel posizionare due visualizzazioni di testo (con lo stesso testo) in un unico punto e dissolvere il primo, in modo che quello in basso (che ha un colore bianco) diventi visibile.

P.S. Ho scartato la variante delle 2 TextView poiché sembrava strano (i bordi non erano lisci e, dato che ho molti di questi elementi sullo schermo, era davvero in ritardo sullo scorrimento). Quello che ho fatto, è stato un pazzo hack che fa l'animazione con l'uso di un Thread e setTextColor (che costringe anche il ridisegno di una textview).

Poiché sono necessari solo 2 cambi di colore (da rosso a bianco e da verde a bianco) ho codificato i valori e tutti i colori di transizione tra loro. Quindi, ecco come appare:

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

risposta

3

Anche se non ho trovato un metodo del tutto distinta, ho cercato di usare un TextSwitcher (con l'animazione fade) per creare l'effetto di cambio colore. A TextSwitcher è un tipo di ViewSwitcher che si anima letteralmente tra due (interni) TextView s. Hai implementato manualmente lo stesso sistema inconsapevolmente? ;) Gestisce un po 'più del processo per te, quindi potresti trovare più facile lavorare con te (specialmente se vuoi provare animazioni più coinvolgenti). Creerei una nuova sottoclasse di TextSwitcher e alcuni metodi, ad es. setColour() che può impostare il nuovo colore e quindi attivare un'animazione. Il codice dell'animazione può quindi essere spostato all'esterno dell'applicazione principale.

  • assicurarsi di mantenere una maniglia sui due TextView s che vengono messi in switcher
  • cambiamento del colore degli altri TextView e chiamare setText() animare tra loro

Se sei già utilizzando un ViewSwitcher quindi non penso che ci sia un modo più semplice per implementare questo.

+0

Grazie . In realtà non ho implementato il metodo di cui stavo parlando (ci ho appena pensato). Grazie mille, proverò ora il tuo metodo :) –

3

Non è necessario mantenere le maniglie per le due visualizzazioni di testo. In primo luogo aggiungere le animazioni fadeIn/FadeOut:

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

poi:

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

appena implementato in questo modo così dimostrato di funzionare.

0

Ho scartato la variante delle 2 TextView poiché sembrava strano (i bordi non erano lisci e, dato che ho molti di questi elementi sullo schermo, era davvero in ritardo sullo scorrimento). Quello che ho fatto, è stato un pazzo hack che fa l'animazione con l'uso di un Thread e setTextColor (che costringe anche il ridisegno di una textview).

Poiché sono necessari solo 2 cambi di colore (da rosso a bianco e da verde a bianco) ho codificato i valori e tutti i colori di transizione tra loro. Quindi, ecco come appare:

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

È possibile utilizzare le nuove Property Animation Api per l'animazione di colore:

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

Per la compatibilità a ritroso con l'utilizzo di Android 2.x Nine Old Androids library da Jake Wharton.

17

la soluzione più semplice è quello di utilizzare Animatori oggetto:

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

questa è la migliore risposta, grazie a –

+0

come controllare la velocità del objectanimator? – pollaris

0

Il problema che ho trovato con valueAnimator così come ObjectAnimator è che i itera animatore attraverso un certo numero di colori casuali, e la transizione non sembra liscio. Ho scritto il seguente codice che ha funzionato senza intoppi. Spero che aiuti anche qualcun altro.

0

Come altri citano, utilizzando ObjectAnimator risolve questo problema. Tuttavia, nei post esistenti, non vedevo come impostare la durata. Per me il cambiamento di colore avverrebbe immediatamente.

La soluzione qui di seguito mostra:

  1. modificando l'animazione con qualche intervallo; grazie al post: https://plus.google.com/+CyrilMottier/posts/X4yoNHHszwq

  2. un senso continuo ciclo avanti e indietro tra le 2 colori


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

meglio usare ValueAnimator e 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(); 
Problemi correlati