效果图如下:
会有打字声音的哦!
关键代码分析:
private void initView() {
release();
mAnimatorTypeText = new ValueAnimator();
mAnimatorTypeText.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
//value的值会重复所以要加判断,避免文字重复打印
if (getText().length() - 1 < value) {
if (value == 0) {
if (mTypeListener != null) {
mTypeListener.onTypeStart();
}
}
startTypeAudio();
append(mText.substring(value, value + 1));
}
if (value >= mTextLength - 1) {
if (mTypeListener != null) {
mTypeListener.onTypeStop();
}
release();
}
}
});
try {
stopTypeAudio();
mMediaPlayer = MediaPlayer.create(getContext(), R.raw.type_in);
} catch (Exception e) {
e.printStackTrace();
}
}复制代码
由于ValueAnimator默认的插值器是AccelerateDecelerateInterpolator也就是先加速后减速(也符合实际情况,开始打字一般都慢些,后面进入状态了快些,快要完成的时候会慢点)onAnimationUpdate造成里面的值是不均匀的,且会有重复,所以加上getText().length() - 1 < value的判断避免同一个子重复添加。
/**
* 切换程序或者按下home键直接setText()
*/
@Override
public Parcelable onSaveInstanceState() {
release();
Bundle bundle = new Bundle();
Parcelable superData = super.onSaveInstanceState();
bundle.putParcelable(DEFAULT_DATA, superData);
bundle.putString(KEY_TEXT, mText);
setText(mText);
return bundle;
}复制代码
当按下home键、切换程序或者页面本后台杀死时,保存文字。如果是前两者情况,由于会有打字声音,所以要先关闭声音和打字动画(release()),直接setText(),不然在桌面或者切换到其他程序如果打字还没完成,还会有打字声音,亦可赛艇。
/**
* 后台杀死回复
* @param state
*/
@Override
public void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
mText = bundle.getString(KEY_TEXT);
setText(mText);
Parcelable superData = bundle.getParcelable(DEFAULT_DATA);
super.onRestoreInstanceState(superData);
}复制代码
如果程序在后台被系统杀死,我们就要取得onSaveInstanceState()保存的值进行现场恢复,注意的是:view的id一定要有,而且onSaveInstanceState()中的
Parcelable superData = super.onSaveInstanceState();
bundle.putParcelable(DEFAULT_DATA, superData);复制代码
以及onRestoreInstanceState()中的
Parcelable superData = bundle.getParcelable(DEFAULT_DATA);
super.onRestoreInstanceState(superData);复制代码
不能少,也就是我们除了处理自己关心的值之外,还要对默认的值进行处理,不然会报错:
12-15 16:58:11.452 13886-13886/com.example.administrator.typewritetextviewdemo E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.administrator.typewritetextviewdemo, PID: 13886 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.administrator.typewritetextviewdemo/com.example.administrator.typewritetextviewdemo.MainActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.os.Bundle instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/ttv. Make sure other views do not use the same id. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413) at android.app.ActivityThread.access$800(ActivityThread.java:155) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5343) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) Caused by: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.os.Bundle instead
github地址觉得对你有帮助给个Star,如果有问题欢迎联系,我会尽快处理!