自定义View实现文本水平方向的跑马灯效果

来源:互联网 发布:华为误删移动用户数据 编辑:程序博客网 时间:2024/05/06 04:30

自定义View实现文本水平方向的跑马灯效果,可以设置文本相关属性及滚动速度,思路是不断执行onDraw()方法绘制文本,缺点显而易见

/** * Created by wyl on 2017/10/26. */public class MarqueeView extends View {    private final float DEF_SIZE = 100.0f;//默认字体大小    private final int DEF_COLOR = 0xffffff;    private float mSpeed = 2.0F; //默认滚动速度    private boolean isScroll = true; //是否自动滚动    private Context mContext;    private Paint mPaint; //文字画笔    private String mText;//展示内容    private float mCoordinateX;//文字起始位置的X轴偏移量    private float mCoordinateY;//Y轴偏移量    private float mTextWidth; //文本的宽度    private int mViewWidth; //控件的宽度    private int mViewHeight;//控件高度    public MarqueeView(Context context) {        super(context);        init(context);    }    public MarqueeView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public MarqueeView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        this.mContext = context;        if (TextUtils.isEmpty(mText)) {            mText = "欢迎光临";        }        mPaint = new Paint();        // mPaint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/msyh.ttf"));        mPaint.setAntiAlias(true);        mPaint.setTextSize(DEF_SIZE);        mPaint.setColor(DEF_COLOR);    }    public void setText(String text) {        mText = text;        if (TextUtils.isEmpty(mText)) {            mText = "欢迎光临!";        }        requestLayout();//设置字体过后 需要重新测量View        invalidate();//重新绘制    }    public void setTextSize(float textSize) {        mPaint.setTextSize(mTextSize <= 0 ? DEF_SIZE : textSize);        requestLayout();        invalidate();    }    public void setTextColor(int textColor) {        mPaint.setColor(mTextColor);        invalidate();    }    //设置滚动速度    public void setTextSpeed(float speed) {        this.mSpeed = speed < 0 ? 0 : speed;        invalidate();    }    //设置滚动    public void setScroll(boolean isScroll) {        this.isScroll = isScroll;        invalidate();    }    //是否滚动    public boolean isScroll() {        return isScroll;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        mTextWidth = mPaint.measureText(mText);//测量文本长度        //从屏幕最右端开始        //  mCoordinateX = getResources().getDisplayMetrics().widthPixels;        mCoordinateX = mViewWidth;        //测量控件宽度        mViewWidth = measureW(widthMeasureSpec);        //测量控件高度        mViewHeight = measureH(heightMeasureSpec);        //测量文本起始位置Y轴的偏移量  使其水平居中        Paint.FontMetricsInt fm = mPaint.getFontMetricsInt();        mCoordinateY = getHeight() / 2 - fm.descent + (fm.descent - fm.ascent) / 2;        //根据文本显示内容选择         //----------------------top        //----------------------ascent        //   内容(中文/英文)        //----------------------baseline        //----------------------descent        //----------------------bottom        //mCoordinateY = getHeight() / 2 - fm.descent + (fm.bottom- fm.top) / 2        setMeasuredDimension(mViewWidth, mViewHeight);    }    private int measureW(int measureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        if (specMode == MeasureSpec.EXACTLY) {//match_parent 或者 具体的值            result = specSize;        } else {//wrap_content 由文本长度 及左右padding决定            result = (int) mPaint.measureText(mText) + getPaddingLeft()                    + getPaddingRight();            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }    private int measureH(int measureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        if (specMode == MeasureSpec.EXACTLY) {//match_parent 或者 具体的值            result = specSize;        } else {//wrap_content 控件高度由字体大小 及 上下padding决定            result = (int) mPaint.getTextSize() + getPaddingTop()                    + getPaddingBottom();            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制文本        canvas.drawText(mText, mCoordinateX, mCoordinateY, mPaint);        //如果不能滚动 则停止绘制        if (!isScroll) {            return;        }        //每绘制一次 X轴的偏移量 减去滚动速度 再进行绘制        mCoordinateX -= mSpeed;        //当文本向左偏移text的宽度后 即所有文字都从屏幕左侧出去后 重置X轴的偏移量 让文字重新由右边进入        if (Math.abs(mCoordinateX) > mTextWidth && mCoordinateX < 0) {            mCoordinateX = mViewWidth;//重置X轴偏移量为控件宽度        }        invalidate();    }}
原创粉丝点击