Skip to content

Instantly share code, notes, and snippets.

@hrules6872
Last active April 13, 2016 15:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hrules6872/fd7f7670a5275d73fb5c to your computer and use it in GitHub Desktop.
Save hrules6872/fd7f7670a5275d73fb5c to your computer and use it in GitHub Desktop.
TextViewWriter
<resources>
<declare-styleable name="TextViewWriter">
<attr name="delay" format="integer"/>
<attr name="autoStart" format="boolean"/>
<attr name="mode" format="enum">
<enum name="character" value="0"/>
<enum name="word" value="1"/>
</attr>
</declare-styleable>
</resources>
public class TextViewWriter extends TextView {
private static final int DEFAULT_DELAY_MS = 150;
private static final boolean DEFAULT_AUTOSTART = false;
public static final int MODE_CHARACTER = 0;
public static final int MODE_WORD = 1;
private static final int DEFAULT_MODE = MODE_CHARACTER;
@Retention(RetentionPolicy.SOURCE) @IntDef({ MODE_CHARACTER, MODE_WORD }) public @interface Mode {
}
private CharSequence text;
private int index;
private long delay;
private int mode;
private boolean paused;
private boolean running;
private ArrayList<TextViewWriterListener> listeners;
private final Handler handler = new Handler();
public TextViewWriter(Context context) {
this(context, null);
}
public TextViewWriter(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TextViewWriter(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TextViewWriter(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextViewWriter);
delay = typedArray.getInt(R.styleable.TextViewWriter_delay, DEFAULT_DELAY_MS);
mode = typedArray.getInt(R.styleable.TextViewWriter_mode, DEFAULT_MODE);
boolean autoStart =
typedArray.getBoolean(R.styleable.TextViewWriter_autoStart, DEFAULT_AUTOSTART);
typedArray.recycle();
if (autoStart) {
playOrResume();
}
}
public void addTextViewWriterListener(TextViewWriterListener listener) {
if (listeners == null) {
listeners = new ArrayList<>();
}
listeners.add(listener);
}
public void removeTextViewWriterListener(TextViewWriterListener listener) {
if (listeners != null) {
int position = listeners.indexOf(listener);
if (position >= 0) {
listeners.remove(position);
}
}
}
public void clearTextViewWriterListener() {
if (listeners != null) {
for (TextViewWriterListener listener : listeners) {
removeTextViewWriterListener(listener);
}
listeners.clear();
listeners = null;
}
}
private final Runnable runnable = new Runnable() {
@Override public void run() {
if (text == null) {
text = "";
}
running = true;
if (mode == MODE_CHARACTER) {
index++;
} else {
int spaceIndex = text.toString().indexOf(" ", index);
if (spaceIndex != -1) {
index = spaceIndex + 1;
} else {
index = text.length();
}
}
setText(text.subSequence(0, index));
if (index < text.length() && !paused) {
handler.postDelayed(runnable, delay);
} else {
running = false;
notifyFinish();
}
}
};
public void play(CharSequence text) {
super.setText(text);
this.text = text;
index = 0;
run();
}
public void play(CharSequence text, int from) {
super.setText(text);
index = from;
run();
}
public void play(int from) {
text = getText();
index = from;
run();
}
public void playOrResume() {
if (getText().equals(text)) {
if (!paused) {
index = 0;
}
} else {
text = getText();
index = 0;
}
run();
}
public void pause() {
paused = true;
notifyPause();
}
public void stop() {
paused = true;
index = 0;
notifyStop();
}
public void end() {
paused = true;
setText(text);
}
private void run() {
paused = false;
if (text != null && text.length() > 0) {
if (index > text.length()) {
index = text.length();
}
setText("");
if (!running) {
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, delay);
}
notifyStart();
}
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
playOrResume();
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
playOrResume();
}
public @Mode int getMode() {
return mode;
}
public void setMode(@Mode int mode) {
this.mode = mode;
playOrResume();
}
private void notifyStop() {
if (listeners != null) {
for (TextViewWriterListener listener : listeners) {
listener.onStop();
}
}
}
private void notifyPause() {
if (listeners != null) {
for (TextViewWriterListener listener : listeners) {
listener.onPause(index);
}
}
}
private void notifyStart() {
if (listeners != null) {
for (TextViewWriterListener listener : listeners) {
listener.onStart();
}
}
}
private void notifyFinish() {
if (listeners != null) {
for (TextViewWriterListener listener : listeners) {
listener.onFinish();
}
}
}
}
public interface TextViewWriterListener {
void onStart();
void onPause(int index);
void onStop();
void onFinish();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment