当文本的最后一个字母可见时,有没有办法重新启动字幕/滚动



我希望文本框中的文本滚动到末尾,然后重新启动。

使用字幕滚动整个文本,直到第一个字母到达";起始点";,但我只希望文本滚动到文本的最后一个字母可见,然后暂停,文本应该跳到开始,然后再次开始滚动。

有办法做到这一点吗。我已经搜索过了,但找不到适合我的东西。

谢谢,Sebi

我不知道有任何方法可以配置TextView来执行您所寻求的字幕行为。我在评论中提到的堆栈溢出问答确实翻译了整个TextView。我认为,如果您在ViewGroup中设置TextView,使TextViewextView的其他一些特性,如阴影、边框和背景,可能看起来不太对劲。

TextView的内容由TextViewcode本身通过画布翻译进行字幕滚动来设置动画。请参见此处。

if (isMarqueeFadeEnabled()) {
if (!mSingleLine && getLineCount() == 1 && canMarquee()
&& (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
final int width = mRight - mLeft;
final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight();
final float dx = mLayout.getLineRight(0) - (width - padding);
canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
if (mMarquee != null && mMarquee.isRunning()) {
final float dx = -mMarquee.getScroll();
canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
}

您还可以考虑编写自定义的TextView并进行自己的文本滚动。你可以查看TextView代码本身,了解如何做到这一点。我认为编写自己的TextView

我已经将GitHub项目中的代码(发布在Cheticamp的评论中(重写为java,并根据我的需要缩短了它。现在它开始无限动画。

这里的java代码:

MarqueTextView.java:

public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView {
private final Scroller mScroller;
private int mDelay;
private int mDuration;
private final Handler mHandler = new Handler();
private final Runnable mAnimateRunnable = new Runnable() {
@Override
public void run() {
//check if Animation is needed otherwise check next cycle (if text has changed for example)
if (getTextViewWidthWithPadding() < getTextWidth()) {
mScroller.startScroll(getStartX(), 0, 0, 0, 0);
invalidate();
int direction = getLayout().getParagraphDirection(0);
mScroller.startScroll(getStartX(), 0, (getTextWidth() - getTextViewWidthWithPadding()) * direction, 0, mDuration);
}
mHandler.postDelayed(mAnimateRunnable, mDelay);
}
};
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
mScroller = new Scroller(context, new LinearInterpolator());
setScroller(mScroller);
}
private int getTextWidth() {
String text = getText().toString();
TextPaint paint = getPaint();
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
return bounds.width();
}
private int getTextViewWidthWithPadding() {
return getWidth() - (getPaddingStart() + getPaddingEnd());
}
private int getStartX() {
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
int lineRight = (int) getLayout().getLineRight(0);
if (isRtl) {
return lineRight - getTextViewWidthWithPadding();
} else {
return 0;
}
}
public void startAnimation(int delay, int duration) {
mDelay = delay;
mDuration = duration;
mHandler.postDelayed(mAnimateRunnable, delay);
}
}

activity_main.xml:

<MarqueeTextView
android:id="@+id/name"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:ellipsize="none"
android:singleLine="true"
android:text="1. Simple text that shows how to use custom marquee"
/>

MainActivty.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((MarqueeTextView)findViewById(R.id.name)).startAnimation(3000, 2000);
}

最新更新