这里需要注意下:
tv2.setSingleLine(); tv2.setHorizontallyScrolling(true); tv2.setEllipsize(TextUtils.TruncateAt.MARQUEE); tv2.setMarqueeRepeatLimit(-1); tv2.setFocusable(true); tv2.setFocusableInTouchMode(true); tv2.requestFocus();
这里可以使用动画的效果实现.
package com.test.marquee; import android.animation.ValueAnimator; 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 android.view.animation.LinearInterpolator; import androidx.annotation.Nullable; public class MarqueeView extends View { private String text; private Paint paint; private float textWidth; private float textX; private float viewWidth; private ValueAnimator animator; public MarqueeView(Context context) { super(context); init(); } public MarqueeView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public MarqueeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { text = "This is a marquee"; paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setTextSize(50); paint.setColor(Color.BLACK); textWidth = paint.measureText(text); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); viewWidth = w; textX = viewWidth; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText(text, textX, getHeight() / 2, paint); } public void startMarquee() { animator= ValueAnimator.ofFloat(viewWidth, -textWidth); animator.setDuration(5000); animator.setInterpolator(new LinearInterpolator()); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(animation -> { textX = (float) animation.getAnimatedValue(); invalidate(); }); animator.start(); } public void stopMarquee() { // 停止动画 if (animator!=null) animator.cancel(); } }
package com.test.marquee; import android.content.Context; import android.graphics.Canvas; import android.text.TextUtils; import android.text.method.ScrollingMovementMethod; import android.util.AttributeSet; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatTextView; public class VerticalMarqueeTextView extends AppCompatTextView { private float offsetY; public VerticalMarqueeTextView(Context context) { super(context); init(); } public VerticalMarqueeTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } private void init() { setSingleLine(); setEllipsize(TextUtils.TruncateAt.MARQUEE); setMarqueeRepeatLimit(-1); setFocusable(true); setFocusableInTouchMode(true); setHorizontallyScrolling(true); setMovementMethod(ScrollingMovementMethod.getInstance()); } @Override protected void onDraw(Canvas canvas) { canvas.translate(0, offsetY); super.onDraw(canvas); } @Override public boolean isFocused() { return true; } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); post(new Runnable() { @Override public void run() { offsetY -= 1; if (offsetY <= -getHeight()) { offsetY = 0; } invalidate(); postDelayed(this, 20); } }); } }