自定義跑馬燈效果,並添加根據屏幕密度自動調整字體大小,詳見註釋
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、效果圖