Java 从左到右连续设置文本动画

Java 从左到右连续设置文本动画,java,android,android-animation,Java,Android,Android Animation,我试图创建一个动画,将TextView从左向右移动并无限循环。这是我要设置动画的TextView: <TextView android:id="@+id/txtTitle" android:layout_width="280dp" android:layout_height="wrap_content" android:textSize="16sp" android:textStyle="italic" android:layout_marg

我试图创建一个动画,将
TextView
从左向右移动并无限循环。这是我要设置动画的
TextView

<TextView
    android:id="@+id/txtTitle"
    android:layout_width="280dp"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:textStyle="italic"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:layout_marginTop="20dp"
    android:ellipsize="end"
    android:maxLines="1"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/cardView" />

我想要实现的是文本从屏幕中央开始,向右移动,一旦第一个字母离开屏幕,它就会在屏幕的另一侧重新出现。

您想要做的事情可以通过简单的
ValueAnimator
轻松实现

首先要做的是将两个相同版本的
TextView
放入布局中。在本例中,我的布局如下所示:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/first"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textSize="32sp"
        android:text="@string/hello_word"/>

    <TextView
        android:id="@+id/second"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textSize="32sp"
        android:text="@string/hello_word"/>

</FrameLayout>
final TextView first = (TextView) findViewById(R.id.first);
final TextView second = (TextView) findViewById(R.id.second);

final ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.setDuration(9000L);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        final float progress = (float) animation.getAnimatedValue();
        final float width = first.getWidth();
        final float translationX = width * progress;
        first.setTranslationX(translationX);
        second.setTranslationX(translationX - width);
    }
});
animator.start();
结果应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/first"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textSize="32sp"
        android:text="@string/hello_word"/>

    <TextView
        android:id="@+id/second"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textSize="32sp"
        android:text="@string/hello_word"/>

</FrameLayout>
final TextView first = (TextView) findViewById(R.id.first);
final TextView second = (TextView) findViewById(R.id.second);

final ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.setDuration(9000L);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        final float progress = (float) animation.getAnimatedValue();
        final float width = first.getWidth();
        final float translationX = width * progress;
        first.setTranslationX(translationX);
        second.setTranslationX(translationX - width);
    }
});
animator.start();

如果有人试图在游戏画布上持续搜索关于文本框的内容,下面是在游戏循环中实现这一点的代码类,它返回一个画布,绘制在游戏界面上,其函数由
gameview
循环调用

public class StartingLine {
private int screenWidth;
private int screenHeight;
private int xStartPosition;
private int yStartPosition;
private int xEndPosition;
private int yEndPosition;
private int width = 50;
private int tv1y = 0;
private int tv2y = 0;
private int tv3y = 0;
private Paint paint;


public StartingLine(Context context, int screenX, int screenY, int laneCount) {
    screenWidth = screenX;
    screenHeight = screenY;
    this.xStartPosition = screenWidth - width - (screenHeight / laneCount) * 2;
    this.yStartPosition = 0;
    this.xEndPosition = screenWidth - width - (screenHeight / laneCount) * 2;
    this.yEndPosition = screenHeight;
    paint = new Paint();
}

public void update(int color) {
    paint.setColor(color);
    paint.setStrokeWidth(2);
    paint.setTextSize(30);
    paint.setTextAlign(Paint.Align.CENTER);
}

public void draw(Canvas canvas) {
    Rect tb = new Rect();
    paint.getTextBounds("STOP AFTER THIS POINT", 0, "STOP AFTER THIS POINT".length(), tb);
    if (tv1y == 0 && tv2y == 0 && tv3y == 0) {
        tv1y = 0;
        tv2y = tb.width() + width;//tb.width()+width = gap between two texts
        tv3y = 2 * (tb.width() + width);
    } else {
        if (tv3y  >= (3 * (tb.width() + width))) {
            tv3y = 2 * (tb.width() + width);
        }

        tv1y = tv3y - 2 * (width + tb.width());
        tv2y = tv1y + width + tb.width();
        tv3y = tv2y + width + tb.width();
    }

    canvas.drawLine(xStartPosition, yStartPosition, xEndPosition, yEndPosition, paint);
    canvas.drawLine(xStartPosition + width, yStartPosition, xEndPosition + width, yEndPosition, paint);
    canvas.save();
    canvas.rotate(270, screenWidth / 2, screenHeight / 2);

    canvas.drawText("STOP AFTER THIS POINT", tv1y += 5, yEndPosition - 20, paint);
    canvas.drawText("STOP AFTER THIS POINT", tv2y += 5, yEndPosition - 20, paint);
    canvas.drawText("STOP AFTER THIS POINT", tv3y += 5, yEndPosition - 20, paint);
    canvas.restore();
}
}

Android有一个内置的解决方案,称为“marquee”

将这些行添加到TextView

<TextView
    android:id="@+id/txtTitle"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
 />

但是,只有当文本足够长以至于超出边界时,这才有效。

作为旁注:您真的应该使用
Animator
API而不是查看动画。
Animator
API是一种更新得多、卓越得多的动画API,它得到了广泛的支持(99%的设备)。根据经验:每个名称中有“动画”的类(例如
TranslateAnimation
)都是旧的view animations API的一部分,所有名称中带有
Animator
的内容都是较新的
Animator
API的一部分。如果我的文本包含多行单词,那么它就不好了。我想为包含多行单词的文本设置动画,但我想将所有单词旋转到一行如何使其无限滚动?