在安卓程序启动的时候,想逐字显示一段话,每个字都有一个从透明到不透明的渐变动画。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类并不支持对单个字符设置动画,所以我们需要创建一个自定义的视图组件来实现这一功能。...
同时,为实现动画效果,可以使用Handler或Runnable配合postDelayed()方法来延迟文本的更新,模拟出逐字逐行滚动的效果。 在"AutoNewLineText"这个压缩包中,很可能包含了一个实现了上述功能的自定义TextView类,...
【Android自定义View实现打字机效果】 在Android开发中,有时为了增加用户界面的趣味性和交互性,我们可能需要创建一些独特的视图组件。"打字机效果"就是这样一个例子,它模拟了老式打字机逐字符显示文本的过程,...
【Android仿打字机打字效果源码】是一种在Android应用开发中实现的动画效果,它模拟了老式打字机的文字输入过程,为用户带来一种独特的交互体验。这种效果通常用于文本显示、消息加载或者文章展示等场景,能够增加...
总结来说,"TestScreenRollView"是一种通过逐字滚动展示文字的动画效果,通过自定义View和动画框架来实现。它的应用可以增加应用的趣味性和互动性,但同时也需要权衡用户体验和视觉效果。对于想要提升应用交互性的...
自定义一个文字动画(轮播图上的两行文字,逐字出现),代码点击查看(之前用ondraw的方法实现,结果发现当文字中有特殊字符的时候,宽度测量会有很大的偏差,所以用了新的方法:添加一个invisiable的textview用来...
BeamTextView 是一个专门为Android平台设计的自定义TextView组件,它能实现类似iOS锁屏界面的文字效果,即“灯光扫射”的动态展示。这个组件通过Java编程语言开发,为开发者提供了更多的自定义选项,使得在Android...
EditText是Android SDK中的一个视图类,继承自TextView,用于接收用户输入的文字信息。开发者通常会通过XML布局文件来定义EditText,并设置其属性,如输入类型(文本、数字、电话号码等)、提示文字、最大输入长度等...
开发者通过重写`onDraw()`方法来实现特定的绘制逻辑,即文本的逐字符动画效果。 2. **动画处理**:为了实现打字机效果,库内部可能使用了`ObjectAnimator`或者`ValueAnimator`来控制文本的显示速度,模拟出打字时...