利用Android中的TextView實(shí)現(xiàn)逐字顯示動畫
前言
Android的TextView只能設(shè)置整個TextView的動畫,而不能設(shè)置每個文字的動畫。即使是使用TextSwitcher,也很難實(shí)現(xiàn)我想要的效果。
所以選擇自定義一個。大體思路是:繼承ViewGroup,設(shè)置Text的時候,每個文字為一個TextView,每隔一個固定時間,啟動每個TextView的動畫。
定義一個CTextView,繼承ViewGroup:
實(shí)現(xiàn)主要代碼:
public class CTextView extends ViewGroup {
}
向外提供一個方法setText(String text, final Animation animation, int duration),text為要顯示的字符串,animation為每個字符的動畫,duration為字符動畫的播放間隔。
該方法實(shí)現(xiàn)如下:
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,并設(shè)置它的動畫
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完整實(shí)現(xiàn)如下:
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,并設(shè)置它的動畫
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);
// 設(shè)置自定義的控件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是精確尺寸,
* 當(dāng)我們將控件的layout_width或layout_height指定為具體數(shù)值時如andorid
* :layout_width="50dip",或者為FILL_PARENT是,都是控件大小已經(jīng)確定的情況,都是精確尺寸。
*
*
* MeasureSpec.AT_MOST是最大尺寸,
* 當(dāng)控件的layout_width或layout_height指定為WRAP_CONTENT時
* ,控件大小一般隨著控件的子空間或內(nèi)容進(jìn)行變化,此時控件尺寸只要不超過父控件允許的最大尺寸即可
* 。因此,此時的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中,調(diào)用CTextView的setText方法,傳入相關(guān)參數(shù)即可:
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);
}
}
其中的第二個參數(shù)為動畫,我想要的效果是從透明到不透明,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>
如果想實(shí)現(xiàn)文字逐個從右側(cè)飛入:
<?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>
總結(jié)
以上就是利用Android中的TextView實(shí)現(xiàn)逐字動畫的全部內(nèi)容,實(shí)現(xiàn)后效果還是很贊的,感興趣的小伙伴們自己動手實(shí)踐起來吧。如果有疑問可以留言討論。
- android實(shí)現(xiàn)上下滾動的TextView
- android TextView不用ScrollViewe也可以滾動的方法
- Android編程實(shí)現(xiàn)自動調(diào)整TextView字體大小以適應(yīng)文字長度的方法
- Android開發(fā)技巧之在a標(biāo)簽或TextView控件中單擊鏈接彈出Activity(自定義動作)
- Android開發(fā):TextView加入滾動條示例
- android動態(tài)布局之動態(tài)加入TextView和ListView的方法
- 基于Android中的 AutoCompleteTextView實(shí)現(xiàn)自動填充
- Android AutoCompleteTextView連接數(shù)據(jù)庫自動提示的方法(附demo源碼下載)
- Android編程實(shí)現(xiàn)TextView部分顏色變動的方法
- Android實(shí)現(xiàn)在TextView文字過長時省略部分或滾動顯示的方法
- Android TextView實(shí)現(xiàn)垂直滾動效果的方法
- Android編程實(shí)現(xiàn)TextView垂直自動滾動功能【附demo源碼下載】
相關(guān)文章
仿餓了嗎點(diǎn)餐界面ListView聯(lián)動的實(shí)現(xiàn)
這篇文章主要介紹了仿餓了嗎點(diǎn)餐界面ListView聯(lián)動的實(shí)現(xiàn)的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下2016-09-09
Android學(xué)習(xí)之Intent中顯示意圖和隱式意圖的用法實(shí)例分析
這篇文章主要介紹了Android學(xué)習(xí)之Intent中顯示意圖和隱式意圖的用法,以實(shí)例形式分析了Intent通訊的相關(guān)技巧與注意事項(xiàng),具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10
Android5.0多種側(cè)滑欄效果實(shí)例代碼
這篇文章主要介紹了Android5.0多種側(cè)滑欄效果實(shí)例代碼的相關(guān)資料,本文圖文并茂介紹的非常詳細(xì),需要的朋友可以參考下2016-09-09
android實(shí)現(xiàn)上下左右滑動界面布局
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)上下左右滑動的界面布局,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-12-12
Flutter使用AnimatedSwitcher實(shí)現(xiàn)場景切換動畫
在應(yīng)用中,我們經(jīng)常會遇到切換組件的場景。本文將利用Flutter中提供的AnimatedSwitcher這一動畫組件來實(shí)現(xiàn)頁面內(nèi)的場景切換,需要的可參考一下2022-03-03
Android用RecyclerView實(shí)現(xiàn)圖標(biāo)拖拽排序以及增刪管理
這篇文章主要介紹了Android用RecyclerView實(shí)現(xiàn)圖標(biāo)拖拽排序以及增刪管理的方法,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03

