实现上下滚动的TextView

实现上下滚动的TextView


一 说明

这里主要使用类 AutoTextView,这是一个自定义的类,继承至TextSwitcher,下面对 AutoTextView类做简要说明:1. 该类使用的重点,在于设置两个动画, setInAnimation(...)  和 setOutAnimation(...),分别是文字进入的动画和文字退出的动画;2. 类中定义了一个内部类-Rotate3dAnimation,主要靠该类实现文字进出动画,该内部类继承至Animation。说来巧合,这个恰好是在apiDemo中看到了,自定义Animation我还是第一次使用,动画逻辑均在void applyTransformation(float interpolatedTime, Transformation t)中实现,代码相当犀利,我在原来的基础上,更改了一下,实现了上述的效果,

二 代码部分:

1.AutoTextView.java

001<font color="#362e2b"><font face="Arial">package com.example.animtextview;
002 
003import android.content.Context;
004import android.content.res.TypedArray;
005import android.graphics.Camera;
006import android.graphics.Matrix;
007import android.util.AttributeSet;
008import android.view.Gravity;
009import android.view.View;
010import android.view.animation.AccelerateInterpolator;
011import android.view.animation.Animation;
012import android.view.animation.Transformation;
013import android.widget.TextSwitcher;
014import android.widget.TextView;
015import android.widget.ViewSwitcher;
016 
017public class AutoTextView extends TextSwitcher implements
018                ViewSwitcher.ViewFactory {
019 
020        private float mHeight;
021        private Context mContext;
022        //mInUp,mOutUp分别构成向下翻页的进出动画
023        private Rotate3dAnimation mInUp;
024        private Rotate3dAnimation mOutUp;
025         
026        //mInDown,mOutDown分别构成向下翻页的进出动画
027        private Rotate3dAnimation mInDown;
028        private Rotate3dAnimation mOutDown;
029         
030        public AutoTextView(Context context) {
031                this(context, null);
032                // TODO Auto-generated constructor stub
033        }
034 
035        public AutoTextView(Context context, AttributeSet attrs) {
036                super(context, attrs);
037                // TODO Auto-generated constructor stub
038                TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.auto3d);
039                mHeight = a.getDimension(R.styleable.auto3d_textSize, 36);
040                a.recycle();
041                mContext = context;
042                init();
043        }
044 
045        private void init() {
046                // TODO Auto-generated method stub
047                setFactory(this);
048                mInUp = createAnim(-90, 0 , true, true);
049                mOutUp = createAnim(0, 90, false, true);
050                mInDown = createAnim(90, 0 , true , false);
051                mOutDown = createAnim(0, -90, false, false);
052                //TextSwitcher主要用于文件切换,比如 从文字A 切换到 文字 B,
053                //setInAnimation()后,A将执行inAnimation,
054                //setOutAnimation()后,B将执行OutAnimation
055        setInAnimation(mInUp);
056        setOutAnimation(mOutUp);
057        }
058         
059        private Rotate3dAnimation createAnim(float start, float end, boolean turnIn, boolean turnUp){
060        final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, turnIn, turnUp);
061        rotation.setDuration(800);
062        rotation.setFillAfter(false);
063        rotation.setInterpolator(new AccelerateInterpolator());
064        return rotation;
065        }
066 
067        //这里返回的TextView,就是我们看到的View
068        @Override
069        public View makeView() {
070                // TODO Auto-generated method stub
071                TextView t = new TextView(mContext);
072                t.setGravity(Gravity.CENTER);
073                t.setTextSize(mHeight);
074                t.setMaxLines(2);
075                return t;
076        }
077        //定义动作,向下滚动翻页
078        public void previous(){
079                if(getInAnimation() != mInDown){
080                        setInAnimation(mInDown);
081                }
082                if(getOutAnimation() != mOutDown){
083                        setOutAnimation(mOutDown);
084                }
085        }
086        //定义动作,向上滚动翻页
087        public void next(){
088                if(getInAnimation() != mInUp){
089                        setInAnimation(mInUp);
090                }
091                if(getOutAnimation() != mOutUp){
092                        setOutAnimation(mOutUp);
093                }
094        }
095         
096         class Rotate3dAnimation extends Animation {
097                    private final float mFromDegrees;
098                    private final float mToDegrees;
099                    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}
147</font></font>


2. MainActivity.java
01package com.example.animtextview;
02 
03import android.os.Bundle;
04import android.app.Activity;
05import android.view.View;
06import android.view.View.OnClickListener;
07import android.widget.Button;
08 
09public 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
01<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    android:layout_width="match_parent"
04    android:layout_height="match_parent"
05    android:orientation="vertical" >
06 
07    <RelativeLayout
08        android:layout_width="match_parent"
09        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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值