一般我们做Android,需要跑马灯的时候都是给TextView添加一下属性即可,但是有时候,会失去焦点,跑马灯效果就消失了,今天写了两种简单的自定义跑马灯效果,不会失去焦点,一直永动。
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
一、继承TextView,拦截焦点消失的方法
直接上代码。
package com.views.custom;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@SuppressLint("AppCompatCustomView")
public class MarqueeTextView extends TextView {
public MarqueeTextView(@NonNull Context context) {
this(context, null);
}
public MarqueeTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MarqueeTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//设置单行
setSingleLine();
//设置Ellipsize
setEllipsize(TextUtils.TruncateAt.MARQUEE);
//获取焦点
// setFocusable(true);
//走马灯的重复次数,-1代表无限重复
setMarqueeRepeatLimit(-1);
//强制获得焦点
// setFocusableInTouchMode(true);
}
public void startAnim() {
setEllipsize(TextUtils.TruncateAt.MARQUEE);
}
public void stopAnim() {
setEllipsize(TextUtils.TruncateAt.END);
}
/**
* 用于EditText抢注焦点的问题
* */
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (focused) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
/**
* Window与Window间焦点发生改变时的回调
* */
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
}
}
/**
*这个属性这个View得到焦点,在这里我们设置为true,这个View就永远是有焦点的
*/
@Override
public boolean isFocused() {
return true;
}
}
二、使用Paint在Canvas上画一个
这个是利用onDraw方法,不断刷新UI的方法。
package com.customview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.R;
public class MarqueeTextView extends View {
private String text; // 要显示的文字
private Paint mPaint; // 画笔
private int textWidth; // 文字宽度
private int x; // 文字的横坐标
public MarqueeTextView(Context context) {
super(context);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void init(String noplay) {
text = noplay;
mPaint = new Paint();
mPaint.setTextSize(32);
mPaint.setColor(getResources().getColor(R.color.color_card_music_owner));
mPaint.setAntiAlias(true);
textWidth = (int) mPaint.measureText(text);
x = getMeasuredWidth();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawText(text, x, 50, mPaint);
x--;
if (x < -textWidth) {
x = getMeasuredWidth()/2;
}
postInvalidateDelayed(10);
}
}
以上就是两种方式,留着以后慢慢使用。