任何人都知道执行动画的任何有效方法,必须做的是逐个字符地显示文本,例如:
Ť
日
氏
这
这个我
这是
...
等等。
谢谢!
答案 0 :(得分:98)
这可能不是最优雅的解决方案,但最简单的可能是TextView
的快速子类Handler
,它会经常更新文本,直到显示完整的序列:
public class Typewriter extends TextView {
private CharSequence mText;
private int mIndex;
private long mDelay = 500; //Default 500ms delay
public Typewriter(Context context) {
super(context);
}
public Typewriter(Context context, AttributeSet attrs) {
super(context, attrs);
}
private Handler mHandler = new Handler();
private Runnable characterAdder = new Runnable() {
@Override
public void run() {
setText(mText.subSequence(0, mIndex++));
if(mIndex <= mText.length()) {
mHandler.postDelayed(characterAdder, mDelay);
}
}
};
public void animateText(CharSequence text) {
mText = text;
mIndex = 0;
setText("");
mHandler.removeCallbacks(characterAdder);
mHandler.postDelayed(characterAdder, mDelay);
}
public void setCharacterDelay(long millis) {
mDelay = millis;
}
}
然后您可以在如下的活动中使用它:
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Typewriter writer = new Typewriter(this);
setContentView(writer);
//Add a character every 150ms
writer.setCharacterDelay(150);
writer.animateText("Sample String");
}
}
如果你想要添加每个字母的一些动画效果,或许要看一下子类化TextSwitcher
。
希望有帮助!
答案 1 :(得分:15)
使用Devunwired的打字机课程
然后,在布局中:
<com.example.fmm.Typewriter
android:id="@+id/typewriter"
android:layout_alignParentTop="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
活动中的代码:
Typewriter writer = (Typewriter)findViewById(R.id.typewriter);
//Add a character every 150ms
writer.setCharacterDelay(150);
writer.animateText("Sample String");
答案 2 :(得分:8)
无需设置额外的课程使用此功能,此处tv是布局中的textview 只需致电
<强> setCharacterDelay(150);
animateText(“Sample String”);
private Handler mHandler = new Handler();
private Runnable characterAdder = new Runnable() {
@Override
public void run() {
tv.setText(mText.subSequence(0, mIndex++));
if(mIndex <= mText.length()) {
mHandler.postDelayed(characterAdder, mDelay);
}
}
};
public void animateText(CharSequence text) {
mText = text;
mIndex = 0;
tv.setText("");
mHandler.removeCallbacks(characterAdder);
mHandler.postDelayed(characterAdder, mDelay);
}
public void setCharacterDelay(long millis) {
mDelay = millis;
}
答案 3 :(得分:3)
Devunwired with xml layout
的新副本 public class Typewriter extends TextView {
private CharSequence mText;
private int mIndex;
private long mDelay = 500; //Default 500ms delay
public Typewriter(Context context) {
super(context);
}
public Typewriter(Context context, AttributeSet attrs) {
super(context, attrs);
}
private Handler mHandler = new Handler();
private Runnable characterAdder = new Runnable() {
@Override
public void run() {
setText(mText.subSequence(0, mIndex++));
if(mIndex <= mText.length()) {
mHandler.postDelayed(characterAdder, mDelay);
}
}
};
public void animateText(CharSequence text) {
mText = text;
mIndex = 0;
setText("");
mHandler.removeCallbacks(characterAdder);
mHandler.postDelayed(characterAdder, mDelay);
}
public void setCharacterDelay(long millis) {
mDelay = millis;
}
}
代码使用
textView = (Typewriter)findViewById(R.id.textView1);
//Add a character every 150ms
textView.setCharacterDelay(150);
textView.animateText("Sample String");
然后在classStart中定义textView
答案 4 :(得分:1)
我使用了一种递归方法,在单词之间还添加了一些延迟,以使人感觉更丰富。 将textView作为视图与文本一起发送,并发送'1'作为长度以从头开始输入
private fun typingAnimation(view: TextView, text: String, length: Int) {
var delay = 100L
if(Character.isWhitespace(text.elementAt(length-1))){
delay = 600L
}
view.text = text.substring(0,length)
when (length) {
text.length -> return
else -> Handler().postDelayed({
typingAnimation(view, text, length+1 )
}, delay)
}
}
答案 5 :(得分:0)
理论上它将是
string text = "hello"
string temp = "h"
iterate: temp += if (text.length > temp.length) text[temp.length]; wait
你当然会在你的runmethod中进行迭代。
答案 6 :(得分:0)
上面提供的大多数解决方案都会产生各种错误。我猜解决方案已经过时了。我偶然发现了这个android studio插件,它就像魅力一样。
1. AutoTypeTextView的安装非常简单。只需添加build.gradle
即可compile&#39; com.krsticdragan:autotypetextview:1.1&#39;
2.添加一个新的命名空间,用于添加AutoTypeTextView并使用其标签。
的xmlns:attv =&#34; HTTP://schemas.android.com/apk/res-auto"
因此,您的根布局应该如下所示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:attv="http://schemas.android.com/apk/res-auto"
将其添加到您的xml文件中。
<com.dragankrstic.autotypetextview.AutoTypeTextView
android:id="@+id/lblTextWithoutMistakes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
attv:animateTextTypeWithoutMistakes="Hello World!" />
只需这三个步骤就可以了。您可以查看the documentation here for more details
答案 7 :(得分:0)
我现在知道它太晚了,但有人仍然可能从谷歌来到这里。 实际上,我的应用程序也需要这样的东西,所以我自己做了一个。 尝试Fade-In TextView,它会使每个角色都显示平滑的alpha动画。用法也很简单。
在XML布局中
<believe.cht.fadeintextview.TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="@android:color/black"
app:letterDuration="250"/>
在活动/片段
中believe.cht.fadeintextview.TextView textView = (believe.cht.fadeintextview.TextView) findViewById(R.id.textView);
textView.setLetterDuration(250); // sets letter duration programmatically
textView.isAnimating(); // returns current animation state (boolean)
textView.setText(); // sets the text with animation
更多信息
Fade-In TextView库直接从本机TextView类继承其属性,这意味着支持所有本机TextView方法。实际上没有任何限制,包括多线支持。该库还有一些自己的方法和属性,可以完全控制View。
答案 8 :(得分:0)
使用Kotlin代码时,只需添加到@Devunwired的答案中,
我更改了(在animateText函数中):
mHandler.postDelayed(mRunnable,mDelay)
至mRunnable.run()
所以我最后的Kotlin课看起来像这样:
class TextViewAnimationComponent(context: Context,attributeSet: AttributeSet?) : TextView(context,attributeSet) {
private var mHandler = Handler()
private var mText:CharSequence = ""
private var mIndex:Int = 0
private var mDelay:Long = 500
private val mRunnable = object: Runnable{
override fun run() {
text = mText.subSequence(0,mIndex++)
if(mIndex <= mText.length){
mHandler.postDelayed(this,mDelay)
}
}
}
fun animateText(mText:CharSequence){
this.mText = mText
mIndex = 0
text = ""
mHandler.removeCallbacks(mRunnable)
mRunnable.run()
// mHandler.postDelayed(mRunnable,mDelay)
}
fun setCharacterDelay(millis:Long){
mDelay = millis
}
}
而且,无需子类即可编写快速且肮脏的代码(仍在Kotlin中)。
内部活动:
private fun animateText(mText: CharSequence, delayMillis: Long, postFunction:() -> Unit){
var mIndex = 0
val runnable = object : Runnable {
override fun run() {
// RunRunnable is a boolean flag; used in case you want to interrupt the execution
if(runRunnable) {
if (mIndex <= mText.length) {
// change textViewSwitchStateValue with your own TextView id
textViewSwitchStateValue.text = mText.subSequence(0, mIndex++)
Handler().postDelayed(this, delayMillis)
} else {
// After all the characters finished animating; Clear the TextView's text and then run the postFunction
textViewSwitchStateValue.text = ""
postFunction()
}
}
}
}
runOnUiThread(runnable)
一个动画化加载点的简单示例:
animateText(". . .", 400){switchStateON()}
答案 9 :(得分:0)
是的,我知道已经有一段时间了,但是我希望可以使用ValueAnimator以其他方式帮助其他人
val text = "This is your sentence"
val textLength = text.length-1
val textView = findViewById<TextView>(R.id.sampleText)
ValueAnimator.ofInt(0, textLength).apply {
var _Index = -1
interpolator = LinearInterpolator()
duration = 2000
addUpdateListener { valueAnimator ->
val currentCharIndex = valueAnimator.animatedValue as Int
if (_Index != currentCharIndex) {
val currentChar = text[currentCharIndex]
textView.text = textView.text.toString().plus(currentChar.toString())
}
_Index = currentCharIndex
}
}.start()
更新
如果您使用的是RxJava,我当然认为是更合适的解决方案,
Observable.range(0, textLength)
.concatMap { Observable.just(it).delay(75, TimeUnit.MILLISECONDS) }
.map { text[it].toString() }
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { char ->
println("Item: $char")
textView.text = textView.text.toString().plus(char)
}
答案 10 :(得分:-1)