1. 程式人生 > >自定義跑馬燈TextView

自定義跑馬燈TextView

public class wxMarQueeText extends android.support.v7.widget.AppCompatTextView {

    private Paint paint;
    private String mText;
    private Rect rect;
    private float offX = 0;
    private float mStep = 2;
    private int scrollNum = 0;

    public wxMarQueeText(Context context) {
        super(context);
        setSingleLine(true);
    }

    public wxMarQueeText(Context context, AttributeSet attrs) {
        super(context, attrs);
        setSingleLine(true);
    }

    public wxMarQueeText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setSingleLine(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mText = getText().toString();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(getCurrentTextColor());
        paint.setTextAlign(Paint.Align.LEFT);//預設text中心是文字左邊,Center是設定初始位置是文字中心
        paint.setTextSize(getTextSize());
        rect = new Rect();

        paint.getTextBounds(mText, 0, mText.length(), rect);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (rect.width() + 10 < getMeasuredWidth()) {//這麼做是為了保證text繪製的準確
            int left = getMeasuredWidth() / 2 - rect.width() / 2; //當文字長度小於整體長度,此時不進行跑馬燈效果處理,將其位置設定在中間。left: 文字距本身左邊的長度
            canvas.drawText(mText, left, getMeasuredHeight() / 2 + (paint.descent() - paint.ascent() / 2), paint);
            return;
        }

        float x, y;

        x = getMeasuredWidth() - offX;
        y = getMeasuredHeight() / 2 + (paint.descent() - paint.ascent() / 2);
        canvas.drawText(mText, x, y, paint);

        offX += mStep;
        if (offX > getMeasuredWidth() + rect.width()) {
            offX = 0;
        }

        //仿照textView Marquee效果,靠邊懸停,第一次不懸停。scrollNum是判斷是否是第一次到最左邊。
        if (x < mStep && x >= 0 && scrollNum < 1) {
            scrollNum++;
            invalidate();
        } else if (x < mStep && x >= 0) {
            postInvalidateDelayed(5000);//懸停5s
        } else {
            invalidate();
        }
    }