Android字符按字符显示文本动画

时间:2011-07-14 21:51:33

标签: android animation text character

任何人都知道执行动画的任何有效方法,必须做的是逐个字符地显示文本,例如:

Ť



这个我 这是
...

等等。

谢谢!

11 个答案:

答案 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"

  1. 将其添加到您的xml文件中。

    <com.dragankrstic.autotypetextview.AutoTypeTextView android:id="@+id/lblTextWithoutMistakes" android:layout_width="wrap_content" android:layout_height="wrap_content" attv:animateTextTypeWithoutMistakes="Hello World!" />

  2. 只需这三个步骤就可以了。您可以查看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)

您可以将此库用于相同的库:TypeWriterView Android library

瞥见图书馆:

ssh