How to delay displaying text in a TextView (verbatim)… here is a solution to the problem.
How to delay displaying text in a TextView (verbatim)
I want the text in
the TextView to be verbatim, or even letter-by-letter, as it is in most role-playing and adventure games with text boxes. A good example of this is what a text stream should look like in the game phoenix wright ( http://youtu.be/2OOX2Gv0768?t=1m7s ).
What I’ve tried so far is:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String text = "test test test test";
String[] split = text.split(" ");
Deque<String> words = new LinkedList<String>();
for (int i = 0; i<split.length; i++)
{
words.addLast(split[i]);
}
showNextWord(words);
}
public void showNextWord(final Deque<String> words)
{
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
TextView t = (TextView) findViewById(R.id.textBox);
t.append(words.pollFirst()+" ");
if (words.size()>0)
showNextWord(words);
}
}, 500);
}
I
tested it on the emulator and it seems to have low performance, and if I start lagging after displaying each letter, the performance is even worse. Latency inconsistency.
Other than that, I would like a more elegant solution. Maybe there are ways to be more flexible about delays? For example. Greater delay after a sentence and so on.
Thank you very much!
Solution
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;
}
}
Then use the above class in your activity like this:
Typewriter writer = new Typewriter(this);
Add a character every 200ms
writer.setCharacterDelay(200);
writer.animateText("Sample String");