Android模仿打字机效果的自定义View实现

一、前言

         在做splash界面的时候,需要做类似于打字机打字的效果,字一个一个地蹦出来,显示每一个字都带有打字的声音。


二、效果演示

         本例自定义View的演示效果如下(PS:一直不知道在Android上怎么录制gif格式的动画,索性在PC上跑Genymotion Android模拟器,然后用LICEcap录屏就可以了。)。





三、实现原理:

         这个其实不难实现,通过一个定时器不断调用TextView的setText就行了,在setText的时候播放打字的音效。具体代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.Timer;  
  2.     import java.util.TimerTask;  
  3.       
  4.     import android.content.Context;  
  5.     import android.media.MediaPlayer;  
  6.     import android.text.TextUtils;  
  7.     import android.util.AttributeSet;  
  8.     import android.widget.TextView;  
  9.       
  10.     import com.uperone.typetextview.R;  
  11.       
  12.     /** 
  13.      * 模拟打字机效果 
  14.      *  
  15.      * */  
  16.     public class TypeTextView extends TextView {  
  17.         private Context mContext = null;  
  18.         private MediaPlayer mMediaPlayer = null;  
  19.         private String mShowTextString = null;  
  20.         private Timer mTypeTimer = null;  
  21.         private OnTypeViewListener mOnTypeViewListener = null;  
  22.         private static final int TYPE_TIME_DELAY = 80;  
  23.         private int mTypeTimeDelay = TYPE_TIME_DELAY; // 打字间隔  
  24.           
  25.         public TypeTextView(Context context, AttributeSet attrs, int defStyle) {  
  26.             super(context, attrs, defStyle);  
  27.             initTypeTextView( context );  
  28.         }  
  29.       
  30.         public TypeTextView(Context context, AttributeSet attrs) {  
  31.             super(context, attrs);  
  32.             initTypeTextView( context );  
  33.         }  
  34.       
  35.         public TypeTextView(Context context) {  
  36.             super(context);  
  37.             initTypeTextView( context );  
  38.         }  
  39.           
  40.         public void setOnTypeViewListener( OnTypeViewListener onTypeViewListener ){  
  41.             mOnTypeViewListener = onTypeViewListener;  
  42.         }  
  43.           
  44.         public void start( final String textString ){  
  45.             start( textString, TYPE_TIME_DELAY );  
  46.         }  
  47.           
  48.         public void start( final String textString, final int typeTimeDelay ){  
  49.             if( TextUtils.isEmpty( textString ) || typeTimeDelay < 0 ){  
  50.                 return;  
  51.             }  
  52.             post( new Runnable( ) {  
  53.                 @Override  
  54.                 public void run() {  
  55.                     mShowTextString = textString;  
  56.                     mTypeTimeDelay = typeTimeDelay;  
  57.                     setText( "" );  
  58.                     startTypeTimer( );  
  59.                     ifnull != mOnTypeViewListener ){  
  60.                         mOnTypeViewListener.onTypeStart( );  
  61.                     }  
  62.                 }  
  63.             });  
  64.         }  
  65.           
  66.         public void stop( ){  
  67.             stopTypeTimer( );  
  68.             stopAudio();  
  69.         }  
  70.           
  71.         private void initTypeTextView( Context context ){  
  72.             mContext = context;  
  73.         }  
  74.           
  75.         private void startTypeTimer( ){  
  76.             stopTypeTimer( );  
  77.             mTypeTimer = new Timer( );  
  78.             mTypeTimer.schedule( new TypeTimerTask(), mTypeTimeDelay );  
  79.         }  
  80.           
  81.         private void stopTypeTimer( ){  
  82.             ifnull != mTypeTimer ){  
  83.                 mTypeTimer.cancel( );  
  84.                 mTypeTimer = null;  
  85.             }  
  86.         }  
  87.           
  88.         private void startAudioPlayer() {  
  89.             stopAudio();  
  90.             playAudio( R.raw.type_in );  
  91.         }  
  92.           
  93.         private void playAudio( int audioResId ){  
  94.             try{  
  95.                 stopAudio( );  
  96.                 mMediaPlayer = MediaPlayer.create( mContext, audioResId );  
  97.                 mMediaPlayer.start( );  
  98.             }catch( Exception e ){  
  99.                 e.printStackTrace();  
  100.             }  
  101.         }  
  102.           
  103.         private void stopAudio( ){  
  104.             if( mMediaPlayer != null && mMediaPlayer.isPlaying( ) ){  
  105.                 mMediaPlayer.stop( );  
  106.                 mMediaPlayer.release( );  
  107.                 mMediaPlayer = null;  
  108.             }  
  109.         }  
  110.           
  111.         class TypeTimerTask extends TimerTask{  
  112.             @Override  
  113.             public void run() {  
  114.                 post(new Runnable( ) {  
  115.                     @Override  
  116.                     public void run() {  
  117.                         if( getText( ).toString( ).length( ) < mShowTextString.length( ) ){  
  118.                             setText( mShowTextString.substring(0, getText( ).toString( ).length( ) + 1 ) );  
  119.                             startAudioPlayer();  
  120.                             startTypeTimer( );  
  121.                         }else{  
  122.                             stopTypeTimer( );  
  123.                             ifnull != mOnTypeViewListener ){  
  124.                                 mOnTypeViewListener.onTypeOver( );  
  125.                             }  
  126.                         }  
  127.                     }  
  128.                 });  
  129.             }  
  130.         }  
  131.           
  132.         public interface OnTypeViewListener{  
  133.             public void onTypeStart( );  
  134.             public void onTypeOver( );  
  135.         }  
  136.     }  

三、实现原理:

         这个其实不难实现,通过一个定时器不断调用TextView的setText就行了,在setText的时候播放打字的音效。具体代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.Timer;  
  2.     import java.util.TimerTask;  
  3.       
  4.     import android.content.Context;  
  5.     import android.media.MediaPlayer;  
  6.     import android.text.TextUtils;  
  7.     import android.util.AttributeSet;  
  8.     import android.widget.TextView;  
  9.       
  10.     import com.uperone.typetextview.R;  
  11.       
  12.     /** 
  13.      * 模拟打字机效果 
  14.      *  
  15.      * */  
  16.     public class TypeTextView extends TextView {  
  17.         private Context mContext = null;  
  18.         private MediaPlayer mMediaPlayer = null;  
  19.         private String mShowTextString = null;  
  20.         private Timer mTypeTimer = null;  
  21.         private OnTypeViewListener mOnTypeViewListener = null;  
  22.         private static final int TYPE_TIME_DELAY = 80;  
  23.         private int mTypeTimeDelay = TYPE_TIME_DELAY; // 打字间隔  
  24.           
  25.         public TypeTextView(Context context, AttributeSet attrs, int defStyle) {  
  26.             super(context, attrs, defStyle);  
  27.             initTypeTextView( context );  
  28.         }  
  29.       
  30.         public TypeTextView(Context context, AttributeSet attrs) {  
  31.             super(context, attrs);  
  32.             initTypeTextView( context );  
  33.         }  
  34.       
  35.         public TypeTextView(Context context) {  
  36.             super(context);  
  37.             initTypeTextView( context );  
  38.         }  
  39.           
  40.         public void setOnTypeViewListener( OnTypeViewListener onTypeViewListener ){  
  41.             mOnTypeViewListener = onTypeViewListener;  
  42.         }  
  43.           
  44.         public void start( final String textString ){  
  45.             start( textString, TYPE_TIME_DELAY );  
  46.         }  
  47.           
  48.         public void start( final String textString, final int typeTimeDelay ){  
  49.             if( TextUtils.isEmpty( textString ) || typeTimeDelay < 0 ){  
  50.                 return;  
  51.             }  
  52.             post( new Runnable( ) {  
  53.                 @Override  
  54.                 public void run() {  
  55.                     mShowTextString = textString;  
  56.                     mTypeTimeDelay = typeTimeDelay;  
  57.                     setText( "" );  
  58.                     startTypeTimer( );  
  59.                     ifnull != mOnTypeViewListener ){  
  60.                         mOnTypeViewListener.onTypeStart( );  
  61.                     }  
  62.                 }  
  63.             });  
  64.         }  
  65.           
  66.         public void stop( ){  
  67.             stopTypeTimer( );  
  68.             stopAudio();  
  69.         }  
  70.           
  71.         private void initTypeTextView( Context context ){  
  72.             mContext = context;  
  73.         }  
  74.           
  75.         private void startTypeTimer( ){  
  76.             stopTypeTimer( );  
  77.             mTypeTimer = new Timer( );  
  78.             mTypeTimer.schedule( new TypeTimerTask(), mTypeTimeDelay );  
  79.         }  
  80.           
  81.         private void stopTypeTimer( ){  
  82.             ifnull != mTypeTimer ){  
  83.                 mTypeTimer.cancel( );  
  84.                 mTypeTimer = null;  
  85.             }  
  86.         }  
  87.           
  88.         private void startAudioPlayer() {  
  89.             stopAudio();  
  90.             playAudio( R.raw.type_in );  
  91.         }  
  92.           
  93.         private void playAudio( int audioResId ){  
  94.             try{  
  95.                 stopAudio( );  
  96.                 mMediaPlayer = MediaPlayer.create( mContext, audioResId );  
  97.                 mMediaPlayer.start( );  
  98.             }catch( Exception e ){  
  99.                 e.printStackTrace();  
  100.             }  
  101.         }  
  102.           
  103.         private void stopAudio( ){  
  104.             if( mMediaPlayer != null && mMediaPlayer.isPlaying( ) ){  
  105.                 mMediaPlayer.stop( );  
  106.                 mMediaPlayer.release( );  
  107.                 mMediaPlayer = null;  
  108.             }  
  109.         }  
  110.           
  111.         class TypeTimerTask extends TimerTask{  
  112.             @Override  
  113.             public void run() {  
  114.                 post(new Runnable( ) {  
  115.                     @Override  
  116.                     public void run() {  
  117.                         if( getText( ).toString( ).length( ) < mShowTextString.length( ) ){  
  118.                             setText( mShowTextString.substring(0, getText( ).toString( ).length( ) + 1 ) );  
  119.                             startAudioPlayer();  
  120.                             startTypeTimer( );  
  121.                         }else{  
  122.                             stopTypeTimer( );  
  123.                             ifnull != mOnTypeViewListener ){  
  124.                                 mOnTypeViewListener.onTypeOver( );  
  125.                             }  
  126.                         }  
  127.                     }  
  128.                 });  
  129.             }  
  130.         }  
  131.           
  132.         public interface OnTypeViewListener{  
  133.             public void onTypeStart( );  
  134.             public void onTypeOver( );  
  135.         }  
  136.     }  

四、使用说明:

1. 在xml文件中定义:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <com.uperone.typetext.view.TypeTextView  
  2.             android:id="@+id/typeTxtId"  
  3.             android:layout_width="fill_parent"  
  4.             android:layout_height="wrap_content"  
  5.             android:layout_centerVertical="true" />  


2. 在代码中实例化:


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mTypeTextView = ( TypeTextView )findViewById(R.id.typeTxtId);  
  2.         mTypeTextView.setOnTypeViewListener( new OnTypeViewListener( ) {  
  3.             @Override  
  4.             public void onTypeStart() {  
  5.                 print( "onTypeStart" );  
  6.             }  
  7.               
  8.             @Override  
  9.             public void onTypeOver() {  
  10.                 print( "onTypeOver" );  
  11.             }  
  12.         });   

 3.  调用start方法:


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mTypeTextView.start( TEST_DATA );  


五、下载地址

         我将这个demo上传到github了,可以在这里下载,随便改。TypeTextView



三、实现原理:

         这个其实不难实现,通过一个定时器不断调用TextView的setText就行了,在setText的时候播放打字的音效。具体代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.Timer;  
  2.     import java.util.TimerTask;  
  3.       
  4.     import android.content.Context;  
  5.     import android.media.MediaPlayer;  
  6.     import android.text.TextUtils;  
  7.     import android.util.AttributeSet;  
  8.     import android.widget.TextView;  
  9.       
  10.     import com.uperone.typetextview.R;  
  11.       
  12.     /** 
  13.      * 模拟打字机效果 
  14.      *  
  15.      * */  
  16.     public class TypeTextView extends TextView {  
  17.         private Context mContext = null;  
  18.         private MediaPlayer mMediaPlayer = null;  
  19.         private String mShowTextString = null;  
  20.         private Timer mTypeTimer = null;  
  21.         private OnTypeViewListener mOnTypeViewListener = null;  
  22.         private static final int TYPE_TIME_DELAY = 80;  
  23.         private int mTypeTimeDelay = TYPE_TIME_DELAY; // 打字间隔  
  24.           
  25.         public TypeTextView(Context context, AttributeSet attrs, int defStyle) {  
  26.             super(context, attrs, defStyle);  
  27.             initTypeTextView( context );  
  28.         }  
  29.       
  30.         public TypeTextView(Context context, AttributeSet attrs) {  
  31.             super(context, attrs);  
  32.             initTypeTextView( context );  
  33.         }  
  34.       
  35.         public TypeTextView(Context context) {  
  36.             super(context);  
  37.             initTypeTextView( context );  
  38.         }  
  39.           
  40.         public void setOnTypeViewListener( OnTypeViewListener onTypeViewListener ){  
  41.             mOnTypeViewListener = onTypeViewListener;  
  42.         }  
  43.           
  44.         public void start( final String textString ){  
  45.             start( textString, TYPE_TIME_DELAY );  
  46.         }  
  47.           
  48.         public void start( final String textString, final int typeTimeDelay ){  
  49.             if( TextUtils.isEmpty( textString ) || typeTimeDelay < 0 ){  
  50.                 return;  
  51.             }  
  52.             post( new Runnable( ) {  
  53.                 @Override  
  54.                 public void run() {  
  55.                     mShowTextString = textString;  
  56.                     mTypeTimeDelay = typeTimeDelay;  
  57.                     setText( "" );  
  58.                     startTypeTimer( );  
  59.                     ifnull != mOnTypeViewListener ){  
  60.                         mOnTypeViewListener.onTypeStart( );  
  61.                     }  
  62.                 }  
  63.             });  
  64.         }  
  65.           
  66.         public void stop( ){  
  67.             stopTypeTimer( );  
  68.             stopAudio();  
  69.         }  
  70.           
  71.         private void initTypeTextView( Context context ){  
  72.             mContext = context;  
  73.         }  
  74.           
  75.         private void startTypeTimer( ){  
  76.             stopTypeTimer( );  
  77.             mTypeTimer = new Timer( );  
  78.             mTypeTimer.schedule( new TypeTimerTask(), mTypeTimeDelay );  
  79.         }  
  80.           
  81.         private void stopTypeTimer( ){  
  82.             ifnull != mTypeTimer ){  
  83.                 mTypeTimer.cancel( );  
  84.                 mTypeTimer = null;  
  85.             }  
  86.         }  
  87.           
  88.         private void startAudioPlayer() {  
  89.             stopAudio();  
  90.             playAudio( R.raw.type_in );  
  91.         }  
  92.           
  93.         private void playAudio( int audioResId ){  
  94.             try{  
  95.                 stopAudio( );  
  96.                 mMediaPlayer = MediaPlayer.create( mContext, audioResId );  
  97.                 mMediaPlayer.start( );  
  98.             }catch( Exception e ){  
  99.                 e.printStackTrace();  
  100.             }  
  101.         }  
  102.           
  103.         private void stopAudio( ){  
  104.             if( mMediaPlayer != null && mMediaPlayer.isPlaying( ) ){  
  105.                 mMediaPlayer.stop( );  
  106.                 mMediaPlayer.release( );  
  107.                 mMediaPlayer = null;  
  108.             }  
  109.         }  
  110.           
  111.         class TypeTimerTask extends TimerTask{  
  112.             @Override  
  113.             public void run() {  
  114.                 post(new Runnable( ) {  
  115.                     @Override  
  116.                     public void run() {  
  117.                         if( getText( ).toString( ).length( ) < mShowTextString.length( ) ){  
  118.                             setText( mShowTextString.substring(0, getText( ).toString( ).length( ) + 1 ) );  
  119.                             startAudioPlayer();  
  120.                             startTypeTimer( );  
  121.                         }else{  
  122.                             stopTypeTimer( );  
  123.                             ifnull != mOnTypeViewListener ){  
  124.                                 mOnTypeViewListener.onTypeOver( );  
  125.                             }  
  126.                         }  
  127.                     }  
  128.                 });  
  129.             }  
  130.         }  
  131.           
  132.         public interface OnTypeViewListener{  
  133.             public void onTypeStart( );  
  134.             public void onTypeOver( );  
  135.         }  
  136.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值