Android按字符显示文字动画



谁知道执行动画的任何有效方法,它必须做的是显示文本,一个字符一个字符?如:

T
Th本


这我

等等

谢谢!

这可能不是最优雅的解决方案,但最简单的可能是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;
    }
}

你可以在Activity中这样使用:

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的子类。

不需要设置一个额外的类使用这个,这里电视是一个textview在你的布局只需调用

setCharacterDelay(150)。
animateText("样本字符串");

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;
}

Devunwired与xml布局的新副本

    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

我使用了递归方法,还在单词之间添加了一点延迟,使其更有人情味。将textView作为视图与文本一起发送,并将'1'作为长度发送到type from start

  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)
    }
}

我知道现在太晚了,但可能还是会有人从谷歌过来。实际上,我的应用也需要这样的东西,所以我自己做了一个。尝试淡出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"/>

在Activity/Fragment

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

更多信息

渐入式TextView库直接从本机TextView类继承其属性,这意味着所有本机TextView方法都被支持。几乎没有任何限制,包括多线支持。该库也有一些自己的方法和属性,提供对View的完全控制。

理论上是


string text = "hello"
string temp = "h"

iterate: temp += if (text.length > temp.length) text[temp.length]; wait

你当然会在你的runmethod中进行迭代

上面提供的大多数解决方案都会抛出各种错误。我想这些解决方案已经过时了。我偶然发现了这个android studio插件,它的工作方式很有魅力。

1。安装AutoTypeTextView非常简单。只需添加build.gradle

编译"com.krsticdragan: autotypetextview: 1.1"

2。添加一个新的命名空间,用于添加AutoTypeTextView和使用它的标签。

xmlns: attv = " 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!" />

  • 有了这三个步骤,你就可以开始了。您可以查看这里的文档了解更多详细信息

    只是为了在使用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()}

    是的,我知道已经有一段时间了,但我希望通过使用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)
            }
    

    最新更新