利用Android中的TextView实现逐字显示动画
程序员文章站
2024-03-06 14:12:14
前言
android的textview只能设置整个textview的动画,而不能设置每个文字的动画。即使是使用textswitcher,也很难实现我想要的效果。
&nb...
前言
android的textview只能设置整个textview的动画,而不能设置每个文字的动画。即使是使用textswitcher,也很难实现我想要的效果。
所以选择自定义一个。大体思路是:继承viewgroup,设置text的时候,每个文字为一个textview,每隔一个固定时间,启动每个textview的动画。
定义一个ctextview,继承viewgroup:
实现主要代码:
public class ctextview extends viewgroup { }
向外提供一个方法settext(string text, final animation animation, int duration)
,text为要显示的字符串,animation为每个字符的动画,duration为字符动画的播放间隔。
该方法实现如下:
public void settext(string text, final animation animation, int duration) { int time = 0; if(text != null && !text.isempty()) { char[] characters = text.tochararray(); for(char c : characters) { final textview t = new textview(context); //遍历传入的字符串的每个字符,生成一个textview,并设置它的动画 t.settext(string.valueof(c)); t.settextsize(28); handler h = new handler(); //每隔duration时间,播放下一个textview的动画 h.postdelayed(new runnable() { @override public void run() { addview(t); t.setanimation(animation); } }, time); time += duration; } } }
ctextview完整实现如下:
import android.content.context; import android.os.handler; import android.util.attributeset; import android.view.view; import android.view.viewgroup; import android.view.animation.animation; import android.widget.textview; /** * created by cchen on 2014/9/2. */ public class ctextview extends viewgroup { private context context; public ctextview(context context) { super(context); this.context = context; } public ctextview(context context, attributeset attrs) { super(context, attrs); this.context = context; } public ctextview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); this.context = context; } public void settext(string text, final animation animation, int duration) { int time = 0; if(text != null && !text.isempty()) { char[] characters = text.tochararray(); for(char c : characters) { final textview t = new textview(context); //遍历传入的字符串的每个字符,生成一个textview,并设置它的动画 t.settext(string.valueof(c)); t.settextsize(28); handler h = new handler(); //每隔duration时间,播放下一个textview的动画 h.postdelayed(new runnable() { @override public void run() { addview(t); t.setanimation(animation); } }, time); time += duration; } } } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { int measurewidth = measurewidth(widthmeasurespec); int measureheight = measureheight(heightmeasurespec); // 计算自定义的viewgroup中所有子控件的大小 measurechildren(widthmeasurespec, heightmeasurespec); // 设置自定义的控件myviewgroup的大小 setmeasureddimension(measurewidth, measureheight); } @override protected void onlayout(boolean changed, int l, int t, int r, int b) { int childleft = 0; // 遍历所有子视图 int childcount = getchildcount(); for (int i = 0; i < childcount; i++) { view childview = getchildat(i); // 获取在onmeasure中计算的视图尺寸 int measureheight = childview.getmeasuredheight(); int measuredwidth = childview.getmeasuredwidth(); //将他们横向排列 childview.layout(childleft, 0, childleft + measuredwidth, measureheight); childleft += measuredwidth; } } private int measurewidth(int pwidthmeasurespec) { int result = 0; int widthmode = measurespec.getmode(pwidthmeasurespec);// 得到模式 int widthsize = measurespec.getsize(pwidthmeasurespec);// 得到尺寸 switch (widthmode) { /** * mode共有三种情况,取值分别为measurespec.unspecified, measurespec.exactly, * measurespec.at_most。 * * * measurespec.exactly是精确尺寸, * 当我们将控件的layout_width或layout_height指定为具体数值时如andorid * :layout_width="50dip",或者为fill_parent是,都是控件大小已经确定的情况,都是精确尺寸。 * * * measurespec.at_most是最大尺寸, * 当控件的layout_width或layout_height指定为wrap_content时 * ,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可 * 。因此,此时的mode是at_most,size给出了父控件允许的最大尺寸。 * * * measurespec.unspecified是未指定尺寸,这种情况不多,一般都是父控件是adapterview, * 通过measure方法传入的模式。 */ case measurespec.at_most: case measurespec.exactly: result = widthsize; break; } return result; } private int measureheight(int pheightmeasurespec) { int result = 0; int heightmode = measurespec.getmode(pheightmeasurespec); int heightsize = measurespec.getsize(pheightmeasurespec); switch (heightmode) { case measurespec.at_most: case measurespec.exactly: result = heightsize; break; } return result; } }
然后在布局文件中使用该自定义组件:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".networktestactivity"> <com.network.cchen.network.ctextview android:id="@+id/ctextview" android:layout_width="match_parent" android:layout_height="match_parent"> </com.network.cchen.network.ctextview> </linearlayout>
在activity中,调用ctextview的settext
方法,传入相关参数即可:
import android.app.activity; import android.os.bundle; import android.view.animation.animationutils; public class testactivity extends activity { @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_network_test); ctextview ctextview = (ctextview) findviewbyid(r.id.ctextview); ctextview.settext("hello world", animationutils.loadanimation(this, r.anim.myanim), 300); } }
其中的第二个参数为动画,我想要的效果是从透明到不透明,myanim.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:duration="1000" android:fromalpha="0.0" android:toalpha="1.0" /> </set>
如果想实现文字逐个从右侧飞入:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="1000" android:fillafter="true" android:fromxdelta="50%p" android:interpolator="@android:anim/anticipate_interpolator" android:toxdelta="0" /> </set>
总结
以上就是利用android中的textview实现逐字动画的全部内容,实现后效果还是很赞的,感兴趣的小伙伴们自己动手实践起来吧。如果有疑问可以留言讨论。
推荐阅读
-
利用Android中的TextView实现逐字显示动画
-
Android中TextView显示插入的图片实现方法
-
Android实现TextView显示HTML加图片的方法
-
Android实现在列表List中显示半透明小窗体效果的控件用法详解
-
Android实现在TextView文字过长时省略部分或滚动显示的方法
-
Android UI设计系列之自定义SwitchButton开关实现类似IOS中UISwitch的动画效果(2)
-
Android实现在TextView文字过长时省略部分或滚动显示的方法
-
Android UI设计系列之自定义SwitchButton开关实现类似IOS中UISwitch的动画效果(2)
-
Android中利用动态加载实现手机淘宝的节日特效
-
Android中利用动态加载实现手机淘宝的节日特效