2011-01-11 58 views
11

Có cách nào để tạo hiệu ứng thay đổi màu văn bản (từ bất kỳ màu nào thành màu trắng) không?Hoạt ảnh màu văn bản

Biến thể duy nhất tôi đưa ra, đặt hai bản xem trước văn bản (cùng một văn bản) vào một vị trí và làm mờ phần trên cùng, vì vậy phần dưới cùng (có màu trắng) sẽ hiển thị.

P.S. Tôi đã loại bỏ các biến thể của 2 TextViews vì nó trông kỳ lạ (các cạnh không mượt mà và, vì tôi có rất nhiều thành phần như vậy trên màn hình, nó thực sự đã làm chậm quá trình cuộn). Những gì tôi đã làm, là một hack điên mà không hoạt hình với việc sử dụng một Thread và setTextColor (mà cũng buộc vẽ lại của một textview).

Vì tôi chỉ cần 2 thay đổi màu (từ đỏ sang trắng, và từ xanh sang trắng), tôi đã mã hóa cứng các giá trị và tất cả các màu chuyển tiếp giữa chúng. Vì vậy, dưới đây là cách có vẻ:

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

Trả lời

3

Mặc dù tôi đã không tìm thấy một phương pháp hoàn toàn khác biệt, tôi đã cố gắng sử dụng một TextSwitcher (với các hình ảnh động mờ dần) để tạo hiệu ứng màu sắc thay đổi. A TextSwitcher là một loại ViewSwitcher có nghĩa đen hoạt hình giữa hai (nội bộ) TextView s. Bạn đã tự thực hiện cùng một hệ thống một cách vô tình? ;) Nó quản lý nhiều hơn một chút của quá trình cho bạn, vì vậy bạn có thể tìm thấy nó dễ dàng hơn để làm việc với (đặc biệt là nếu bạn muốn thử hình ảnh động tham gia nhiều hơn). Tôi sẽ tạo lớp con mới của TextSwitcher và một số phương pháp, ví dụ: setColour() có thể đặt màu mới và sau đó kích hoạt hoạt ảnh. Mã hoạt ảnh sau đó có thể được di chuyển ra ngoài ứng dụng chính của bạn.

  • chắc chắn rằng bạn giữ một tay cầm ở hai TextView s được đưa vào switcher
  • thay đổi màu sắc của TextView khác và gọi setText() animate giữa chúng

Nếu bạn đã bằng cách sử dụng một ViewSwitcher thì tôi không nghĩ rằng có một cách dễ dàng hơn để thực hiện điều này.

+0

Cảm ơn . Tôi thực sự đã không thực hiện phương pháp tôi đã nói về (chỉ nghĩ về nó). Cảm ơn rất nhiều, tôi sẽ thử phương pháp của bạn ngay bây giờ :) –

3

Không cần phải giữ tay cầm cho hai chế độ xem văn bản. Đầu tiên thêm các hình ảnh động fadeIn/fadeOut:

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

thì:

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

Chỉ cần thực hiện nó như thế này để chứng minh để làm việc.

0

Tôi đã loại bỏ biến thể của 2 TextView vì nó trông kỳ lạ (cạnh không mượt mà và vì tôi có nhiều thành phần như vậy trên màn hình nên nó thực sự bị trễ). Những gì tôi đã làm, là một hack điên mà không hoạt hình với việc sử dụng một Thread và setTextColor (mà cũng buộc vẽ lại của một textview).

Vì tôi chỉ cần 2 thay đổi màu (từ đỏ sang trắng, và từ xanh sang trắng), tôi đã mã hóa cứng các giá trị và tất cả các màu chuyển tiếp giữa chúng. Vì vậy, dưới đây là cách có vẻ:

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

Bạn có thể sử dụng mới Property Animation Api cho phim hoạt hình màu:

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

Đối với khả năng tương thích ngược với việc sử dụng Android 2.x Nine Old Androids library từ Jake Wharton.

17

Giải pháp dễ nhất sẽ được sử dụng hoạt hình Object:

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

đây là câu trả lời hay nhất, cảm ơn –

+0

làm thế nào để kiểm soát tốc độ của bộ đối tượng? – pollaris

0

Vấn đề tôi thấy với valueAnimator cũng như ObjectAnimator là lặp phim hoạt hình thông qua một số màu sắc ngẫu nhiên, và quá trình chuyển đổi không giống trơn tru. Tôi đã viết đoạn mã sau hoạt động trơn tru. Hy vọng nó cũng giúp người khác.

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

Như những người khác đề cập, sử dụng ObjectAnimator giải quyết cho việc này. Tuy nhiên, trong các bài đăng hiện có - tôi không thấy cách đặt thời lượng. Đối với tôi, sự thay đổi màu sắc sẽ xảy ra ngay lập tức.

Các giải pháp dưới đây cho thấy:

  1. thiết lập các hình ảnh động với một số khoảng thời gian; nhờ gửi: https://plus.google.com/+CyrilMottier/posts/X4yoNHHszwq

  2. một cách để tiếp tục chu kỳ qua lại giữa 2 màu sắc


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

cách tốt nhất sử dụng ValueAnimator và 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(); 
Các vấn đề liên quan