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"
Добавьте это в ваш 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();