Android закадровое отображение текстовой анимации

Кто-нибудь знает какой-либо эффективный метод выполнения анимации, который заключается в том, чтобы отображать текст, символ за символом?, например:

T
Th
Thi
это
Это я
Это
...

и так далее.

Спасибо!

12 ответов

Решение

Возможно, это не самое элегантное решение, но самое простое - это, вероятно, быстрый подкласс 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 вместо.

Надеюсь, это поможет!

Использовать класс пишущей машинки 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");

Нет необходимости устанавливать дополнительный класс. Используйте это, здесь телевизор - это текстовое представление в вашем макете просто позвоните

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

Эта новая копия для 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");

затем определите textView в classStart

Я использовал рекурсивный метод, также добавил немного задержки между словами, чтобы иметь больше человеческого восприятия. Отправьте 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)
    }
}

Я знаю, что уже слишком поздно, но кто-то еще может прийти сюда из Google. На самом деле, мне тоже нужно что-то подобное для моего приложения, поэтому сделал его сам. Попробуйте Fade-In TextView, он заставляет каждого персонажа появляться с плавной альфа-анимацией. Использование также довольно просто.

В макете 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.

Просто чтобы добавить к ответу @Devunwired при работе с кодом Kotlin,
я изменил (в функции 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()}

Этот способ очень простой и КРАСИВЫЙ

      fun TextView.animateTextWithUnderscore(mText: CharSequence, delayMillis: Long = 15) {
    text = null
    var index = 0
    val handler = Handler()

    val typewriterRunnable = object : Runnable {
        override fun run() {
            val newText = "${mText.subSequence(0, index)}_" <-- underscore is optioanal
            text = newText

            if (index < mText.length) {
                handler.postDelayed(this, delayMillis)
            }
            index++
        }
    }

    handler.postDelayed(typewriterRunnable, delayMillis)
}

Большинство приведенных выше решений приводят к различным ошибкам. Я думаю, что решения старые. Я наткнулся на этот плагин для 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"

  1. Добавьте это в ваш XML-файл.

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

Только с этими тремя шагами вы можете идти. Вы можете проверить документацию здесь для более подробной информации

Да, я знаю, что прошло много времени, но я надеюсь помочь другим с другим подходом с помощью 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)
        }

В теории это было бы


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

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

Вы, конечно, выполните итерацию в вашем методе выполнения.

Вы можете использовать эту библиотеку для того же: Библиотека Android TypeWriterView

Взгляд в библиотеку:

    //Create Object and refer to layout view
    TypeWriterView typeWriterView=(TypeWriterView)findViewById(R.id.typeWriterView);

    //Setting each character animation delay
    typeWriterView.setDelay(int);

    //Setting music effect On/Off
    typeWriterView.setWithMusic(boolean);

    //Animating Text
    typeWriterView.animateText(string);

    //Remove Animation. This is required to be called when you want to minimize the app while animation is going on. Call this in onPause() or onStop()
    typeWriterView.removeAnimation();
Другие вопросы по тегам