简体   繁体   中英

Coloring TextView during a certain time period Android

Is there a way to color text in TextView or something else in Android during certain time period. So it would start off with fully white text and then the coloring would move from left to right and fill it up during a certain duration .
So for example if the duration would be 10 then the whole line should be color in 10 seconds, but it should also move with the same pace.

Which would look something like this:

在此处输入图片说明

There is a way to do it on IOS with CATextLayer , but I haven't yet found a way to do it on Android .

I'm just creating a self-defined TextView in last year,here is my class

public class AKChangeColorTextView extends TextView {
    public AKChangeColorTextView(Context context) {
        this(context,null);
    }
    String TAG = "AKChangeColorTextView";
    public AKChangeColorTextView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    RectF mRectF;
    float mX;
    float mY;
    public AKChangeColorTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLUE);
        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
        mPaint.setXfermode(mode);
        float x = 60;
        float y = 10;
        mY =    0;
        mRectF = new RectF(x, y, x + 50, y + 50);
        mTPaint = getPaint();
        mX = 0;
    }

    Paint mPaint;
    TextPaint mTPaint;
    Bitmap shadowBitmap ;
    Rect bounds = new Rect();
    Canvas textCanvas;

    @Override
    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        if (shadowBitmap == null) {
            shadowBitmap = Bitmap.createBitmap(getMeasuredWidth(),getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        }
        if (textCanvas == null) {
            textCanvas = new Canvas(shadowBitmap);
        }
        textCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        if (mTPaint == null) {
            mTPaint = getPaint();
        }
        String content  = getText().toString();
        mTPaint.getTextBounds(content,0,content.length(),bounds);
        textCanvas.drawText(content,0,bounds.height(),mTPaint);
        mRectF.set(colorLeft,mY,colorRight,mY+bounds.height()+10);
        textCanvas.drawRect(mRectF,mPaint);
        canvas.drawBitmap(shadowBitmap,0,0,null);
    }
    float colorLeft;
    float colorRight;
    public void setXOffset(float left,float right){
        colorLeft = left;
        colorRight = right;
        invalidate();
    }

}

my demo code:

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"
    lateinit var countDownTimer:CountDownTimer
    var currentOffsetx = 0
    var textWidth = 0
    var isIncrease = true
    lateinit var txt:AKChangeColorTextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        (findViewById<View>(R.id.tv_hello) as AKChangeColorTextView).apply{
            txt = this
        }

        countDownTimer = object:CountDownTimer(300000,200){
            override fun onFinish() {
            }

            override fun onTick(millisUntilFinished: Long) {
                if (textWidth == 0) {
                    textWidth = txt.width
                }
                if (currentOffsetx <= textWidth) {
                    if (isIncrease) {
                        currentOffsetx += 10
                        currentOffsetx = min(currentOffsetx, textWidth)
                    } else {
                        currentOffsetx -= 10
                        currentOffsetx = max(currentOffsetx, 0)
                    }
                }
                if (currentOffsetx == textWidth) {
                    isIncrease = false
                }else if (currentOffsetx == 0) {
                    isIncrease = true
                }
                txt.setXOffset(0f,currentOffsetx.toFloat())
                Log.w(TAG,"check current tick:$millisUntilFinished,offsetx:$currentOffsetx,txtWidth:$textWidth")
            }
        }
        countDownTimer.start()
    }

}

my xml layout :

<com.example.administrator.myapplication.AKChangeColorTextView
            android:id="@+id/tv_hello"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="I Found a Love For Aolphn"
            android:textColor="#000000"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

following is effect

在此处输入图片说明

There is a way to do this optimized, simple, smooth and beautiful: Vector Animated Drawables (API21+) .

There are a lot of tutorials out there (for example this video) that show how you can make beautiful animations. Basically the steps are following:

  • create two SVG vector images of your text, one with normal color, the other one with colored letters. You can do this easily in Adobe Illustrator for example.
  • Import both into shapeshifter.design .

  • Create an animation for the second (colored layer) by your liking.

  • Copy the resulting xml file into your drawables and you're done!

Good luck!

您可以使用文本可跨度和前景颜色跨度并一次为一个字符设置动画

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM