android字体打印动画,利用Android中的TextView实现逐字显示动画

前言

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,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,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,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;

}

}

然后在布局文件中使用该自定义组件:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".NetworkTestActivity">

android:id="@+id/cTextView"

android:layout_width="match_parent"

android:layout_height="match_parent">

在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:

android:duration="1000"

android:fromAlpha="0.0"

android:toAlpha="1.0" />

如果想实现文字逐个从右侧飞入:

android:duration="1000"

android:fillAfter="true"

android:fromXDelta="50%p"

android:interpolator="@android:anim/anticipate_interpolator"

android:toXDelta="0" />

总结

以上就是利用Android中的TextView实现逐字动画的全部内容,实现后效果还是很赞的,感兴趣的小伙伴们自己动手实践起来吧。如果有疑问可以留言讨论。

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

小编个人微信号 jb51ccc

喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值