实现上下滚动的TextView

先看一下效果图吧:


一 说明

这里主要使用类 AutoTextView,这是一个自定义的类,继承至TextSwitcher,下面对 AutoTextView类做简要说明:

1. 该类使用的重点,在于设置两个动画, setInAnimation(...)  和 setOutAnimation(...),分别是文字进入的动画和文字退出的动画;

2. 类中定义了一个内部类-Rotate3dAnimation,主要靠该类实现文字进出动画,该内部类继承至Animation。说来巧合,这个恰好是在apiDemo中看到了,自定义Animation我还是第一次使用,动画逻辑均在void applyTransformation(float interpolatedTime, Transformation t)中实现,代码相当犀利,我在原来的基础上,更改了一下,实现了上述的效果,

二 代码部分:

 1.AutoTextView.java

[java]  view plain copy
  1. package com.example.animtextview;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.graphics.Camera;  
  6. import android.graphics.Matrix;  
  7. import android.util.AttributeSet;  
  8. import android.view.Gravity;  
  9. import android.view.View;  
  10. import android.view.animation.AccelerateInterpolator;  
  11. import android.view.animation.Animation;  
  12. import android.view.animation.Transformation;  
  13. import android.widget.TextSwitcher;  
  14. import android.widget.TextView;  
  15. import android.widget.ViewSwitcher;  
  16.   
  17. public class AutoTextView extends TextSwitcher implements  
  18.         ViewSwitcher.ViewFactory {  
  19.   
  20.     private float mHeight;  
  21.     private Context mContext;  
  22.     //mInUp,mOutUp分别构成向下翻页的进出动画  
  23.     private Rotate3dAnimation mInUp;  
  24.     private Rotate3dAnimation mOutUp;  
  25.       
  26.     //mInDown,mOutDown分别构成向下翻页的进出动画  
  27.     private Rotate3dAnimation mInDown;  
  28.     private Rotate3dAnimation mOutDown;  
  29.       
  30.     public AutoTextView(Context context) {  
  31.         this(context, null);  
  32.         // TODO Auto-generated constructor stub  
  33.     }  
  34.   
  35.     public AutoTextView(Context context, AttributeSet attrs) {  
  36.         super(context, attrs);  
  37.         // TODO Auto-generated constructor stub  
  38.         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.auto3d);  
  39.         mHeight = a.getDimension(R.styleable.auto3d_textSize, 36);  
  40.         a.recycle();  
  41.         mContext = context;  
  42.         init();  
  43.     }  
  44.   
  45.     private void init() {  
  46.         // TODO Auto-generated method stub  
  47.         setFactory(this);  
  48.         mInUp = createAnim(-900 , truetrue);  
  49.         mOutUp = createAnim(090falsetrue);  
  50.         mInDown = createAnim(900 , true , false);  
  51.         mOutDown = createAnim(0, -90falsefalse);  
  52.         //TextSwitcher主要用于文件切换,比如 从文字A 切换到 文字 B,  
  53.         //setInAnimation()后,A将执行inAnimation,  
  54.         //setOutAnimation()后,B将执行OutAnimation  
  55.         setInAnimation(mInUp);  
  56.         setOutAnimation(mOutUp);  
  57.     }  
  58.       
  59.     private Rotate3dAnimation createAnim(float start, float end, boolean turnIn, boolean turnUp){  
  60.         final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, turnIn, turnUp);  
  61.         rotation.setDuration(800);  
  62.         rotation.setFillAfter(false);  
  63.         rotation.setInterpolator(new AccelerateInterpolator());  
  64.         return rotation;  
  65.     }  
  66.   
  67.     //这里返回的TextView,就是我们看到的View  
  68.     @Override  
  69.     public View makeView() {  
  70.         // TODO Auto-generated method stub  
  71.         TextView t = new TextView(mContext);  
  72.         t.setGravity(Gravity.CENTER);  
  73.         t.setTextSize(mHeight);  
  74.         t.setMaxLines(2);  
  75.         return t;  
  76.     }  
  77.     //定义动作,向下滚动翻页  
  78.     public void previous(){  
  79.         if(getInAnimation() != mInDown){  
  80.             setInAnimation(mInDown);  
  81.         }  
  82.         if(getOutAnimation() != mOutDown){  
  83.             setOutAnimation(mOutDown);  
  84.         }  
  85.     }  
  86.     //定义动作,向上滚动翻页  
  87.     public void next(){  
  88.         if(getInAnimation() != mInUp){  
  89.             setInAnimation(mInUp);  
  90.         }  
  91.         if(getOutAnimation() != mOutUp){  
  92.             setOutAnimation(mOutUp);  
  93.         }  
  94.     }  
  95.       
  96.      class Rotate3dAnimation extends Animation {  
  97.             private final float mFromDegrees;  
  98.             private final float mToDegrees;  
  99.             private float mCenterX;  
  100.             private float mCenterY;  
  101.             private final boolean mTurnIn;  
  102.             private final boolean mTurnUp;  
  103.             private Camera mCamera;  
  104.   
  105.             public Rotate3dAnimation(float fromDegrees, float toDegrees, boolean turnIn, boolean turnUp) {  
  106.                 mFromDegrees = fromDegrees;  
  107.                 mToDegrees = toDegrees;  
  108.                 mTurnIn = turnIn;  
  109.                 mTurnUp = turnUp;  
  110.             }  
  111.   
  112.             @Override  
  113.             public void initialize(int width, int height, int parentWidth, int parentHeight) {  
  114.                 super.initialize(width, height, parentWidth, parentHeight);  
  115.                 mCamera = new Camera();  
  116.                 mCenterY = getHeight() / 2;  
  117.                 mCenterX = getWidth() / 2;  
  118.             }  
  119.               
  120.             @Override  
  121.             protected void applyTransformation(float interpolatedTime, Transformation t) {  
  122.                 final float fromDegrees = mFromDegrees;  
  123.                 float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);  
  124.   
  125.                 final float centerX = mCenterX ;  
  126.                 final float centerY = mCenterY ;  
  127.                 final Camera camera = mCamera;  
  128.                 final int derection = mTurnUp ? 1: -1;  
  129.   
  130.                 final Matrix matrix = t.getMatrix();  
  131.   
  132.                 camera.save();  
  133.                 if (mTurnIn) {  
  134.                     camera.translate(0.0f, derection *mCenterY * (interpolatedTime - 1.0f), 0.0f);  
  135.                 } else {  
  136.                     camera.translate(0.0f, derection *mCenterY * (interpolatedTime), 0.0f);  
  137.                 }  
  138.                 camera.rotateX(degrees);  
  139.                 camera.getMatrix(matrix);  
  140.                 camera.restore();  
  141.   
  142.                 matrix.preTranslate(-centerX, -centerY);  
  143.                 matrix.postTranslate(centerX, centerY);  
  144.             }  
  145.      }  
  146. }  

2. MainActivity.java

[java]  view plain copy
  1. package com.example.animtextview;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8.   
  9. public class MainActivity extends Activity implements OnClickListener {  
  10.   
  11.     private Button mBtnNext;  
  12.     private Button mBtnPrev;  
  13.     private AutoTextView mTextView02;  
  14.     private static int sCount = 10;  
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.         init();  
  20.     }  
  21.     private void init() {  
  22.         // TODO Auto-generated method stub  
  23.         mBtnNext = (Button) findViewById(R.id.next);  
  24.         mBtnPrev = (Button) findViewById(R.id.prev);  
  25.         mTextView02 = (AutoTextView) findViewById(R.id.switcher02);  
  26.         mTextView02.setText("Hello world!");  
  27.         mBtnPrev.setOnClickListener(this);  
  28.         mBtnNext.setOnClickListener(this);  
  29.     }  
  30.       
  31.     @Override  
  32.     public void onClick(View arg0) {  
  33.         // TODO Auto-generated method stub  
  34.         switch (arg0.getId()) {  
  35.         case R.id.next:  
  36.             mTextView02.next();  
  37.             sCount++;  
  38.             break;  
  39.         case R.id.prev:  
  40.             mTextView02.previous();  
  41.             sCount--;  
  42.             break;  
  43.         }  
  44.         mTextView02.setText(sCount%2==0 ?   
  45.                 sCount+"AAFirstAA" :  
  46.                 sCount+"BBBBBBB");  
  47.         System.out.println("getH: ["+mTextView02.getHeight()+"]");  
  48.           
  49.     }  
  50. }  

3. activity_main.xml

[java]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:auto3d="http://schemas.android.com/apk/res/com.example.animtextview"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <RelativeLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content" >  
  10.   
  11.         <Button  
  12.             android:id="@+id/next"  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_alignParentLeft="true"  
  16.             android:layout_alignParentTop="true"  
  17.             android:text="@string/next" />  
  18.   
  19.         <Button  
  20.             android:id="@+id/prev"  
  21.             android:layout_width="wrap_content"  
  22.             android:layout_height="wrap_content"  
  23.             android:layout_alignParentRight="true"  
  24.             android:layout_alignParentTop="true"  
  25.             android:text="@string/prev" />  
  26.     </RelativeLayout>  
  27.   
  28.     <com.example.animtextview.AutoTextView  
  29.         android:id="@+id/switcher02"  
  30.         android:layout_width="match_parent"  
  31.         android:layout_height="wrap_content"  
  32.         android:background="@android:color/holo_green_dark"  
  33.         auto3d:textSize="30sp" />  
  34.   
  35. </LinearLayout>  


代码中没写太多注释,不过结构还算清晰,应该不难看懂!

三 小结

我认为该控件实现的难点在于 动画文件的编写,即Rotate3dAnimation中applyTransformation(...)方法的实现,通过控制camara在Y方向上移动和在X方向上的旋转,从而造成上下翻滚的视觉感,然后将该值转换到matrix上,从而改变了参数(..,Transformation t).有兴趣的朋友可以直接改写该方法,即可得到不同动画效果的TextSwitcher.

原文地址: http://blog.csdn.net/zjc08125/article/details/8953140

转载请注明出处

四 源代码

源码地址:http://download.csdn.net/detail/zjc08125/5424183


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值