欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 自定义TextView,水平滚动

程序员文章站 2022-09-02 17:40:43
package com.my.androidtext.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.os.Parcel;import android.os.Parcelable;import android.text.TextPaint;import ....
package com.my.androidtext.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import androidx.appcompat.widget.AppCompatTextView;


public class HorizontalTextView extends AppCompatTextView {
    private float textLength = 0f;
    private float viewWidth = 0f;
    private float viewHeight = 0f;
    private float step = 0f;
    private float y = 0f;
    public boolean isStarting = false;
    private Paint paint = null;
    private Paint mBitPaint = null;
    private Bitmap mBitmap;
    private String text = "";
    private boolean isInit = false;
    private boolean isCanScroll = true;
    private static final String POINT = "...";
    private boolean textMarginRight = false;

    public HorizontalTextView(Context context) {
        super(context);
        initTextView();
    }

    public HorizontalTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initTextView();
    }

    public HorizontalTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initTextView();
    }


    @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);

        ss.step = step;
        ss.isStarting = isStarting;

        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());

        step = ss.step;
        isStarting = ss.isStarting;

    }

    public static class SavedState extends View.BaseSavedState {
        public boolean isStarting = false;
        public float step = 0.0f;

        SavedState(Parcelable superState) {
            super(superState);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeBooleanArray(new boolean[]{isStarting});
            out.writeFloat(step);
        }


        public static final Creator<SavedState> CREATOR
                = new Creator<SavedState>() {

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }

            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }
        };

        private SavedState(Parcel in) {
            super(in);
            try {
                boolean[] b = null;
                in.readBooleanArray(b);
                if (b != null && b.length > 0)
                    isStarting = b[0];
                step = in.readFloat();
            } catch (Exception e) {

            }
        }
    }

    public void setCanScroll(boolean canScroll) {
        isCanScroll = canScroll;
    }

    public void setTextMarginRight(boolean textMarginRight) {
        this.textMarginRight = textMarginRight;
    }

    private void startScroll() {
        isStarting = true;
        invalidate();
    }


    private void stopScroll() {
        isStarting = false;
        invalidate();
    }

    @Override
    public void onDraw(Canvas canvas) {
        if (!isInit) {
            initTextView();
        }
        canvas.drawText(text, step, y, paint);

        if (!isStarting) {
            return;
        }
        step -= 1;
        if (-step > textLength)
            step = viewWidth;
        invalidate();
    }


    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        isInit = false;
    }

    private void initTextView() {
        paint = this.getPaint();
        paint.setColor(getCurrentTextColor());
        paint.setTextSize(getTextSize());

        text = this.getText().toString().trim();
        textLength = paint.measureText(text);

        step = 0;

        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        ///文字一半的高度再减去基线到bottom的高度,
        float halfHeight = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        y = getHeight() / 2 + (int) halfHeight;

        if (textLength > viewWidth) {
            if (isCanScroll) {
                startScroll();
            } else {
                reInitTextWithPoint();
                stopScroll();
            }
        } else {
            if (textMarginRight) {
                step = viewWidth - textLength;
            }
            stopScroll();
        }
        isInit = true;
    }

    private void reInitTextWithPoint() {
        TextPaint textPaint = new TextPaint();
        textPaint.setTextSize(this.getTextSize());
        while (textPaint.measureText(text) >= (viewWidth - textPaint.measureText(POINT))) {
            text = text.substring(0, text.length() - 1);
        }
        text += POINT;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        viewWidth = View.MeasureSpec.getSize(widthMeasureSpec);
        viewHeight = View.MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension((int) viewWidth, (int) viewHeight);
    }
}

本文地址:https://blog.csdn.net/winskyan/article/details/108736794

相关标签: Android textview