自定義橫向跑馬燈文字效果

自定義跑馬燈效果,並添加根據屏幕密度自動調整字體大小,詳見註釋

1、自定義控件

package net.edaibu.testapplication.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

/**
 * @author geqipeng
 * @date 2017/11/27
 */

public class CustomTextView extends TextView {


    /**
     * 界面刷新時間(ms)
     */
    public static final int INVALIDATE_TIME = 15;
    /**
     * 每次移動的像素點(px)
     */
    public static final int INVALIDATE_STEP = 1;
    /**
     * 一次移動完成後等待的時間(ms)
     */
    public static final int WAIT_TIME = 1500;
    /**
     * 滾動文字前後的間隔
     */
    private String space = "       ";
    private String drawingText = "";
    private TextPaint paint;
    public boolean exitFlag;
    private float textWidth;
    private String mText;
    /***
     * 設置移動的起點默認從x軸0點開始
     */
    private int posX = 0;
    private float posY;
    private int width;
    private RectF rf;
    private Context mContext;
    /**
     * 設置標記防止多次屏幕變化影響移動速度
     */
    private static boolean b = true;

    private Handler mHandler = new Handler();

    public CustomTextView(Context context) {
        this(context, null);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        initView();
    }


    private void initView() {
        int textSize = getMatrixTextSize();
        paint = new TextPaint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);
        paint.setTextSize(textSize);
        rf = new RectF(0, 0, 0, 0);

    }

    /**
     * 根據屏幕尺寸設置字體大小
     *
     * @return
     */
    private int getMatrixTextSize() {
        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
        int mScreenWidth = dm.widthPixels;
        int mScreenHeight = dm.heightPixels;

        //以分辨率爲720*1280準,計算寬高比值
        float ratioWidth = (float) mScreenWidth / 720;
        float ratioHeight = (float) mScreenHeight / 1280;
        float ratioMetrics = Math.min(ratioWidth, ratioHeight);
        return Math.round(25 * ratioMetrics);
    }

    public void setText(String text) {
        this.mText = text;
        this.drawingText = mText;
        layoutView();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
        layoutView();
    }

    private void layoutView() {
        //獲取控件的寬度作爲矩形的寬度
        width = getWidth();
        rf.right = width;
        //獲取控件的高度作爲矩形的高度
        rf.bottom = getHeight();
        textWidth = paint.measureText(mText, 0, mText.length());
        posY = getTextDrawingBaseline(paint, rf);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getVisibility() != View.VISIBLE || TextUtils.isEmpty(drawingText)) {
            return;
        }
        canvas.save();
        canvas.drawText(drawingText, 0, drawingText.length(), posX, posY, paint);
        canvas.restore();
    }

    private Runnable moveRun = new Runnable() {

        @Override
        public void run() {
            //控制文本寬度大於控件寬度才進行滾動
            if (width >= textWidth) {
                return;
            }
            //繪製的全部內容爲:文字+空格+文字
            drawingText = mText + space + mText;
            //左移
            posX -= INVALIDATE_STEP;
            //當移動到文字頭部,等待,並刷新頁面,即此處設置移動速度爲1,即位於-0.5至+0.5之間時進行等待刷新
            if (posX >= -1 * INVALIDATE_STEP / 2 && posX <= INVALIDATE_STEP / 2) {
                mHandler.postDelayed(this, WAIT_TIME);
                invalidate();
                return;
            }
            //當文字和空格完全移出屏幕,x值從1開始移動
            if (posX < -1 * textWidth - paint.measureText(space, 0, space.length())) {
                posX = INVALIDATE_STEP;
            }
            invalidate();
            if (!exitFlag) {
                mHandler.postDelayed(this, INVALIDATE_TIME);
                return;
            }
            posX = 0;
        }
    };

    /**
     * 從窗口中移除時停止滾動
     */
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        b = true;
        stopMove();
    }

    /**
     * 窗口焦點變化開始滾動
     *
     * @param hasWindowFocus
     */
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        layoutView();
        if (b) {
            b = false;
            startMove();
        }

    }

    private void stopMove() {
        exitFlag = true;
        mHandler.removeCallbacksAndMessages(this);
    }

    public void startMove() {
        exitFlag = false;
        mHandler.post(moveRun);
    }


    /**
     * 獲取繪製文字的baseline
     *
     * @param paint
     * @param targetRect
     * @return
     */
    public static float getTextDrawingBaseline(Paint paint, RectF targetRect) {
        if (paint == null || targetRect == null) {
            return 0;
        }
        Paint.FontMetrics fontMetric = paint.getFontMetrics();
        return targetRect.top + (targetRect.height() - fontMetric.bottom + fontMetric.top) / 2.0f - fontMetric.top;
    }
}

2、activity中使用

public class CustomTextActivity extends Activity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_text);
        init();
    }

    private void init() {
        CustomTextView textThree=findViewById(R.id.tv_text_three);
        textThree.setTextColor(Color.BLACK);
        textThree.setText("我是跑馬燈效果文字,我要不停地跑");



    }
}

3、xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/color_black"
    >

    <net.edaibu.testapplication.view.CustomTextView
        android:id="@+id/tv_text_three"
        android:layout_width="145dp"
        android:layout_height="20dp"
        android:textColor="@color/color_white"
        android:textSize="12sp"
        android:layout_margin="10dp"/>


</RelativeLayout>

4、效果圖


參考:http://jingbin4679.iteye.com/blog/2233406


發佈了105 篇原創文章 · 獲贊 35 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章