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

一、前言

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

二、效果演示

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

三、实现原理:

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

import java.util.Timer;
	import java.util.TimerTask;

	import android.content.Context;
	import android.media.MediaPlayer;
	import android.text.TextUtils;
	import android.util.AttributeSet;
	import android.widget.TextView;

	import com.uperone.typetextview.R;

	/**
	 * 模拟打字机效果
	 *
	 * */
	public class TypeTextView extends TextView {
		private Context mContext = null;
		private MediaPlayer mMediaPlayer = null;
		private String mShowTextString = null;
		private Timer mTypeTimer = null;
		private OnTypeViewListener mOnTypeViewListener = null;
		private static final int TYPE_TIME_DELAY = 80;
		private int mTypeTimeDelay = TYPE_TIME_DELAY; // 打字间隔

		public TypeTextView(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			initTypeTextView( context );
		}

		public TypeTextView(Context context, AttributeSet attrs) {
			super(context, attrs);
			initTypeTextView( context );
		}

		public TypeTextView(Context context) {
			super(context);
			initTypeTextView( context );
		}

		public void setOnTypeViewListener( OnTypeViewListener onTypeViewListener ){
			mOnTypeViewListener = onTypeViewListener;
		}

		public void start( final String textString ){
			start( textString, TYPE_TIME_DELAY );
		}

		public void start( final String textString, final int typeTimeDelay ){
			if( TextUtils.isEmpty( textString ) || typeTimeDelay < 0 ){
				return;
			}
			post( new Runnable( ) {
				@Override
				public void run() {
					mShowTextString = textString;
					mTypeTimeDelay = typeTimeDelay;
					setText( "" );
					startTypeTimer( );
					if( null != mOnTypeViewListener ){
						mOnTypeViewListener.onTypeStart( );
					}
				}
			});
		}

		public void stop( ){
			stopTypeTimer( );
			stopAudio();
		}

		private void initTypeTextView( Context context ){
			mContext = context;
		}

		private void startTypeTimer( ){
			stopTypeTimer( );
			mTypeTimer = new Timer( );
			mTypeTimer.schedule( new TypeTimerTask(), mTypeTimeDelay );
		}

		private void stopTypeTimer( ){
			if( null != mTypeTimer ){
				mTypeTimer.cancel( );
				mTypeTimer = null;
			}
		}

		private void startAudioPlayer() {
			stopAudio();
			playAudio( R.raw.type_in );
		}

		private void playAudio( int audioResId ){
			try{
				stopAudio( );
	            mMediaPlayer = MediaPlayer.create( mContext, audioResId );
	            mMediaPlayer.start( );
	        }catch( Exception e ){
	            e.printStackTrace();
	        }
		}

		private void stopAudio( ){
			if( mMediaPlayer != null && mMediaPlayer.isPlaying( ) ){
	            mMediaPlayer.stop( );
	            mMediaPlayer.release( );
	            mMediaPlayer = null;
	        }
		}

		class TypeTimerTask extends TimerTask{
			@Override
			public void run() {
				post(new Runnable( ) {
					@Override
					public void run() {
						if( getText( ).toString( ).length( ) < mShowTextString.length( ) ){
							setText( mShowTextString.substring(0, getText( ).toString( ).length( ) + 1 ) );
							startAudioPlayer();
							startTypeTimer( );
						}else{
							stopTypeTimer( );
							if( null != mOnTypeViewListener ){
								mOnTypeViewListener.onTypeOver( );
							}
						}
					}
				});
			}
		}

		public interface OnTypeViewListener{
			public void onTypeStart( );
			public void onTypeOver( );
		}
	}

四、使用说明:

1. 在xml文件中定义:

<com.uperone.typetext.view.TypeTextView
	        android:id="@+id/typeTxtId"
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content"
	        android:layout_centerVertical="true" />

2. 在代码中实例化:

mTypeTextView = ( TypeTextView )findViewById(R.id.typeTxtId);
		mTypeTextView.setOnTypeViewListener( new OnTypeViewListener( ) {
			@Override
			public void onTypeStart() {
				print( "onTypeStart" );
			}

			@Override
			public void onTypeOver() {
				print( "onTypeOver" );
			}
		});	

3.  调用start方法:

mTypeTextView.start( TEST_DATA );

五、下载地址

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

时间: 2024-10-29 11:01:52

Android模仿打字机效果的自定义View实现的相关文章

android:模拟水波效果的自定义View

Github地址:https://github.com/nuptboyzhb/WaterWaveView 欢迎Fork,欢迎Star 1.先看效果 2.再看关键代码 描绘函数y = Asin(wx+d)+offset /** * 使用路径描绘绘制的区域 * * @return */ private Path getFristWavePath() { // 绘制区域1的路径 if (firstWavePath == null) { firstWavePath = new Path(); } fir

Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面布局实现如下: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&

Android软件开发之盘点自定义View界面大合集(二)

Android软件开发之盘点自定义View界面大合集(二) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的自定义View界面的绘制 今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧. 1.自定义view绘制字符串 相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便 省内存 我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要 而且使用它还可以带来一个更重要的好处就是很方

Android中实现Bitmap在自定义View中的放大与拖动

一:基本实现思路 基于View类实现自定义View –MyImageView类.在使用View的Activity类中完成OnTouchListener接口,实现对自定义View的触摸事件监听 放大与拖动 基于单点触控实现Bitmap对象在View上的拖动.并且检测View的边缘,防止拖动过界.基于两个点触控实现Bitmap对象在View上的放大.并且检测放大倍数.基于Matrix对象实现对Bitmap在View上放大与平移变换 Bitmap对象在View中的更新与显示 通过重载onDraw方法,

Android初级教程初谈自定义view自定义属性

有些时候,自己要在布局文件中重复书写大量的代码来定义一个布局.这是最基本的使用,当然要掌握:但是有些场景都去对应的布局里面写对应的属性,就显得很无力.会发现,系统自带的控件无法满足我们的要求,这个时候就要考虑自定义控件.自定义view的世界,也很浩瀚,个人需要学的地方还有很多很多.自定义view,会节省开发效率,很有必要学习其基本原理和方法.接下来就对自定义view,做一个初步的认识,一步步了解封装的重要性.但是,也仅仅是一个初步,因为它实在太灵活了. 有这么一种场景,看图: 除了布局之外,还有

Android Studio开发基础之自定义View组件

一般情况下,不直接使用View和ViewGroup类,而是使用使用其子类.例如要显示一张图片可以用View类的子类ImageView,开发自定义View组件可分为两个主要步骤: 一.创建一个继承自android.view.View类的View类,并且重写构造方法. 如下,新建一个名为MyView.Java的Java类文件,重写一个带Context的构造方法和onDraw()方法(用来重新绘制Activity窗口的背景). package com.example.lhb.contentprovid

Android学习(十七)自定义View控件 TopBar

一.创建自定义TopBar头部菜单条 实现步骤: 1.在values中添加attrs.xml文件,设置自定义属性. 2.添加Topbar类,继承RelativeLayout,实现具体功能. 3.添加到页面上,并设置添加事件. 参考代码: values\attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Top

翻翻git之---&quot;有趣效果&quot;的自定义View EasyArcLoading

转载请注明出处:王亟亟的大牛之路 早上写了一个关于MD的文章,下午给编译器调了个色,感觉要上天了,所以为了试颜色就出了这篇文章,让大家一起瞎一下 好了废话不说,这一片给大家介绍一个当做Dialog作用的自定义View 效果图: How to use? Gradle dependencies { com.camnter.easyarcloading:easyarcloading:1.0 } Eclipse: 把实现类和资源文件copy进去就好了 使用的话就直接XML加载,像这样 <?xml ver

Android进阶:九、自定义View之手写Loading动效

这是一个很简单的动画效果,使用属性动画即可实现,希望对读者学习动画能达到抛砖引玉的效果 一.自定义动画效果--Loading效果 如上是我们需要做的一个Loading动画.Loading效果是很常见的一种动画,最简单的实现让设计画个动态图即可,或者画个静态图然后使用帧动画也可以实现.但是今天我们用纯代码实现,不用任何图片资源.大致思路我们自定义一个View,继承View类,然后画两个不同半径的弧形,转动不同的角度即可实现.绘制两个不同半径的弧形首先初始化外圆和内园的Recf(); private