我有一个带有一些文本的TextView,我想让它用滚动的选框动画制作动画。我看到这个popular question关于强制选框动画,但是答案中的代码只有在文本足够长以超出TextView的边界(因此文本被截断)时才有效,我正在寻找一个无论文本的宽度如何,永久使文本都具有此选框动画的解决方案;这有可能吗?
答案 0 :(得分:16)
制作自己的动画。
<强>动画/ marquee.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%"
android:toXDelta="-100%"
android:duration="10000"
android:repeatCount="infinite"
android:repeatMode="restart"
android:interpolator="@android:anim/linear_interpolator"/>
</set>
并在您的活动中
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
TextView myTextView = (TextView) findViewById(R.id.myTextView);
Animation marquee = AnimationUtils.loadAnimation(this, R.anim.marquee);
myTextView.startAnimation(marquee);
}
答案 1 :(得分:3)
考虑到@ JodiMiddleton关于填充文本的建议,我构建了一些辅助方法,根据TextPaint对象将文本填充到目标宽度(确保在测量时正确调整字体等大小):
/**
* Pad a target string of text with spaces on the right to fill a target
* width
*
* @param text The target text
* @param paint The TextPaint used to measure the target text and
* whitespaces
* @param width The target width to fill
* @return the original text with extra padding to fill the width
*/
public static CharSequence padText(CharSequence text, TextPaint paint, int width) {
// First measure the width of the text itself
Rect textbounds = new Rect();
paint.getTextBounds(text.toString(), 0, text.length(), textbounds);
/**
* check to see if it does indeed need padding to reach the target width
*/
if (textbounds.width() > width) {
return text;
}
/*
* Measure the text of the space character (there's a bug with the
* 'getTextBounds() method of Paint that trims the white space, thus
* making it impossible to measure the width of a space without
* surrounding it in arbitrary characters)
*/
String workaroundString = "a a";
Rect spacebounds = new Rect();
paint.getTextBounds(workaroundString, 0, workaroundString.length(), spacebounds);
Rect abounds = new Rect();
paint.getTextBounds(new char[] {
'a'
}, 0, 1, abounds);
float spaceWidth = spacebounds.width() - (abounds.width() * 2);
/*
* measure the amount of spaces needed based on the target width to fill
* (using Math.ceil to ensure the maximum whole number of spaces)
*/
int amountOfSpacesNeeded = (int)Math.ceil((width - textbounds.width()) / spaceWidth);
// pad with spaces til the width is less than the text width
return amountOfSpacesNeeded > 0 ? padRight(text.toString(), text.toString().length()
+ amountOfSpacesNeeded) : text;
}
/**
* Pads a string with white space on the right of the original string
*
* @param s The target string
* @param n The new target length of the string
* @return The target string padded with whitespace on the right to its new
* length
*/
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
因此,当您使用基于TextView的方法时,您会调用:
textView.setText(padText(myTargetString, textView.getPaint(), textView.getWidth()));
它并不优雅,我几乎可以确定可以做出哪些改进(更不用说更好的方法),但我仍然在我的使用中代码,它似乎正在做的伎俩:)
答案 2 :(得分:1)
听起来很脏但是阻力最小的路径可能是用空格填充文本以允许滚动。
如果需要,您可以在Click上删除它们。
答案 3 :(得分:0)
字幕动画字幕
public class MarqueeLayout extends FrameLayout {
private Animation animation;
public MarqueeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, +1f,
Animation.RELATIVE_TO_SELF, -1f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f
);
animation.setRepeatCount(Animation.INFINITE);
animation.setRepeatMode(Animation.RESTART);
}
public void setDuration(int durationMillis) {
animation.setDuration(durationMillis);
}
public void startAnimation() {
startAnimation(animation);
}
}
布局:
<MarqueeLayout
android:id="@+id/marquee_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/message_text"
android:singleLine="true"
android:textColor="@color/marquee_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</MarqueeLayout>
活动:
MarqueeLayout marqueeLayout = (MarqueeLayout) view.findViewById(R.id.marquee_layout);
marqueeLayout.setDuration(15000);
marqueeLayout.startAnimation();
答案 4 :(得分:0)
我找到了一个可以解决问题的单行代码!
只需重复几次您的短文本,或用长的空格分隔它们。
activity_main.xml
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text=""
android:textColor="#ffffff"/>
MainActivity.java
String shortText = "A short text.";
TextView textView = findViewById(R.id.textView);
textView.setText(shortText + " " + shortText);
// repeat the above concatenation as many as required
// just enough to make it marqueeable for auto scrolling
// or you can just increase the length of the blank space
textView.setSelected(true);
答案 5 :(得分:0)
要使大量文本通过屏幕,请执行以下操作:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate
android:fromXDelta="300%"
android:toXDelta="-100%"
android:duration="5000"
android:repeatCount="infinite"
android:repeatMode="restart"
/>
</set>