原创首发
【自定义View】自动滚动的TextView(跑马灯)——可获取完成一次滚动后的监听

AutoRollTextViewByRunnable类
class AutoRollTextViewByRunnable extends androidx.appcompat.widget.AppCompatTextView implements Runnable {
String TAG = "MarqueeText";
private int currentScrollX = 0;// 当前滚动的位置
private int textWidth;
private int viewWidth;
private boolean isMeasure = false;
private boolean isRoll = false;
AgainListener againListener;
//动画效果
ObjectAnimator animator1;
ObjectAnimator animator2;
public AutoRollTextViewByRunnable(Context context) {
super(context);
init();
}
public AutoRollTextViewByRunnable(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AutoRollTextViewByRunnable(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
void init() {
setGravity(Gravity.CENTER_VERTICAL);
setSingleLine();
setEllipsize(TextUtils.TruncateAt.MARQUEE);
startScroll();
addTextChangedListener(textWatcher);
//动画效果
animator1 = ObjectAnimator.ofFloat(this, "alpha", 0f);
animator2 = ObjectAnimator.ofFloat(this, "alpha", 1f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isMeasure) {
textWidth = getTextWidth();
viewWidth = getWidth();
isMeasure = true;
}
}
TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
animator1.setDuration(0);
animator2.setStartDelay(500);
animator2.setDuration(500);
animator2.setInterpolator(new LinearInterpolator());
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playSequentially(animator1, animator2);
animatorSet.start();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
textWidth = getTextWidth();
}
};
@Override
public void run() {
if (textWidth > viewWidth) {
//需要滚动
currentScrollX += 3;
scrollTo(currentScrollX, 0);
if (getScrollX() > textWidth) {
againListener.Again();
currentScrollX = -viewWidth;
scrollTo(currentScrollX, 0);
}
postDelayed(this, 5);
} else {
//无需滚动
scrollTo(0, 0);
postDelayed(this, 500);
}
}
public void startScroll() {
post(this);
}
public void stopScroll() {
this.removeCallbacks(this);
}
/**
* 获取文字宽度
*/
public int getTextWidth() {
Paint paint = this.getPaint();
String str = this.getText().toString();
return (int) paint.measureText(str);
}
public AgainListener getAgainListener() {
return againListener;
}
public void setAgainListener(AgainListener againListener) {
this.againListener = againListener;
}
interface AgainListener {
void Again();
}
}
2、使用(xml忽略)
AutoRollTextViewByRunnable marqueeText;
//完成一次滚动的监听
marqueeText.setAgainListener(new AutoRollTextViewByRunnable.AgainListener() {
@Override
public void Again() {
Log.d(TAG, "Again: ");
}
});