如何在Android中对TextView应用从左到右的颜色渐变?

6

你好,我需要为textview应用颜色过渡效果,然后跳转到下一个屏幕。我尝试使用spannable string在textview中使用静态颜色,但是我无法应用动态颜色过渡效果。这是我尝试过的内容。

public class AppActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    TextView tv = (TextView) findViewById(R.id.text);
    Spannable text = new SpannableStringBuilder("Loading..");
    setSpan(tv, text);
    tv.setText(text);
}

private void setSpan(TextView tv, Spannable text) {
    int blueColor = 0xff0000ff;
    int redColor = 0xffff0000;
    ForegroundColorSpan blue = new ForegroundColorSpan(blueColor);
    ForegroundColorSpan red = new ForegroundColorSpan(redColor);
    HalfColorApply o = new HalfColorApply("o", tv, blueColor, redColor);
    text.setSpan(blue, 0, 1, 0);
    text.setSpan(o, 1, 2, 0);
    text.setSpan(red, 2, text.length(), 0);
    }

 class HalfColorApply extends DynamicDrawableSpan {
    private final static String TAG = "DrawableSpanTest";
    Picture mPicture;

    public HalfColorApply(String text, TextView tv, int c0, int c1) {
        super(ALIGN_BASELINE);
        mPicture = new Picture();
        TextPaint p = tv.getPaint();
        Rect bounds = new Rect();
        p.getTextBounds(text, 0, text.length(), bounds);
        float width = p.measureText(text);
        float height = bounds.height();
        float y = height;
        Canvas c = mPicture.beginRecording((int) width, (int) height);
        c.save(Canvas.CLIP_SAVE_FLAG);
        // c.drawColor(0x[masked]);
        p = new TextPaint(p);
        p.setColor(c0);
        c.clipRect(0, 0, width / 2, height, Region.Op.REPLACE);
        c.drawText(text, 0, y, p);
        p.setColor(c1);
        c.clipRect(width / 2, 0, width, height, Region.Op.REPLACE);
        c.drawText(text, 0, y, p);
        c.restore();
        mPicture.endRecording();
    }

    @Override
    public Drawable getDrawable() {
        PictureDrawable d = new PictureDrawable(mPicture);
        d.setBounds(0, 0, mPicture.getWidth(), mPicture.getHeight());
        return d;
    }
}
}

这里有一张截图,我在固定的文本上应用了颜色渐变效果,需要在textview上实现。谢谢。

使用LinearGradient并通过从左到右移动来进行动画处理。 - pskink
当进行动画制作时,请使用ValueAnimator/ObjectAnimator,您可以自行选择使用哪种。 - pskink
2个回答

3
您应该使用 ValueAnimator 来编写这段代码。
Kotlin 代码:
fun changeTextColor(textView: TextView, fromColor: Int, toColor: Int, direction: Int = View.LAYOUT_DIRECTION_LTR,duration:Long = 200) {

    var startValue = 0
    var endValue = 0
    if(direction == View.LAYOUT_DIRECTION_LTR){
        startValue = 0
        endValue = textView.text.length
    }
    else if(direction == View.LAYOUT_DIRECTION_RTL) {
        startValue = textView.text.length
        endValue = 0
    }

    textView.setTextColor(fromColor)
    val valueAnimator = ValueAnimator.ofInt(startValue, endValue)
    valueAnimator.addUpdateListener { animator ->
        val spannableString = SpannableString(
            textView.text
        )

        if (direction == View.LAYOUT_DIRECTION_LTR) spannableString.setSpan(
            ForegroundColorSpan(
                toColor
            ), startValue, animator.animatedValue.toString().toInt(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        else if (direction == View.LAYOUT_DIRECTION_RTL) spannableString.setSpan(
            ForegroundColorSpan(
                toColor
            ), animator.animatedValue.toString().toInt(),spannableString.length , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        textView.text = spannableString
    }
    valueAnimator.duration = duration
    valueAnimator.start()
}

只需要简单地使用:

changeTextColor(
            yourTextView,
            Color.BLACK,
            Color.WHITE,
            View.LAYOUT_DIRECTION_LTR,
            300
        )

0

找到解决方案了。

public class SplashActivity extends Activity {
private TextView textView;
private Handler handler;
private long startTime, currentTime, finishedTime = 0L;
private int duration = 22000 / 4;// 1 character is equal to 1 second. if want to
                         // reduce. can use as divide
                         // by 2,4,8
private int endTime = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.test);
    textView = (TextView) findViewById(R.id.textView1);
    textView.setText("Loading.Please wait...");// length of string is 22
    handler = new Handler();
    startTime = Long.valueOf(System.currentTimeMillis());
    currentTime = startTime;

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {

            currentTime = Long.valueOf(System.currentTimeMillis());
            finishedTime = Long.valueOf(currentTime)
                    - Long.valueOf(startTime);

            if (finishedTime >= duration + 30) {
                Toast.makeText(SplashActivity.this, "Move to next screen",
                        Toast.LENGTH_LONG).show();
            } else {
                endTime = (int) (finishedTime / 250);// divide this by
                // 1000,500,250,125
                Spannable spannableString = new SpannableString(textView
                        .getText());
                spannableString.setSpan(new ForegroundColorSpan(
                        Color.YELLOW), 0, endTime,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                textView.setText(spannableString);
                handler.postDelayed(this, 10);
            }
        }
    }, 10);
}

}

enter image description here


这很有帮助,但是它一次只突出显示一个字符?需求不是要有更流畅的动画,每个字符逐渐填充吗? - Harsh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接