Android 实现跑马灯效果
Android中实现跑马灯效果有多种方式,本篇简单介绍下:
1: TextView属性实现
<TextViewandroid:layout_width="150dp"android:layout_height="wrap_content"android:background="#77000000"android:padding="5dp"android:singleLine="true"android:ellipsize="marquee"android:scrollHorizontally="true"android:focusable="true"android:focusableInTouchMode="true"android:marqueeRepeatLimit="marquee_forever"android:text="这是textview的跑马灯效果"android:id="@+id/tv1"/>
这里需要注意下:
- 需要限制textview的宽度,不能设置为wrap_content
- 启动跑马灯效果需要获取焦点requestFocus().
2: 代码实现
tv2.setSingleLine();
tv2.setHorizontallyScrolling(true);
tv2.setEllipsize(TextUtils.TruncateAt.MARQUEE);
tv2.setMarqueeRepeatLimit(-1);
tv2.setFocusable(true);
tv2.setFocusableInTouchMode(true);
tv2.requestFocus();
3: 自定义 view实现
这里可以使用动画的效果实现.
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);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);viewWidth = w;textX = viewWidth;}@Overrideprotected 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();}
}
4: 实现竖直效果的跑马灯
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());}@Overrideprotected void onDraw(Canvas canvas) {canvas.translate(0, offsetY);super.onDraw(canvas);}@Overridepublic boolean isFocused() {return true;}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();post(new Runnable() {@Overridepublic void run() {offsetY -= 1;if (offsetY <= -getHeight()) {offsetY = 0;}invalidate();postDelayed(this, 20);}});}
}