欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android实现上下滚动的TextView

程序员文章站 2023-11-20 17:45:04
一 说明    这里重要应用类 autotextview,这是一个自定义的类,继承至textswitcher,下面临 autotextview...

一 说明
    这里重要应用类 autotextview,这是一个自定义的类,继承至textswitcher,下面临 autotextview类做简要说明:

    1. 该类应用的重点,在于设置两个动画, setinanimation(...)  和 setoutanimation(...),分离是文字进入的动画和文字退出的动画;

    2. 类中定义了一个外部类-rotate3danimation,重要靠该类实现文字进出动画,该外部类继承至animation。说来偶合,这个恰好是在apidemo中看到了,自定义animation我还是第一次应用,动画逻辑均在void applytransformation(float interpolatedtime, transformation t)中实现,代码相当锋利,我在原来的基础上,更改了一下,实现了上述的效果,

二 代码部分:
1.autotextview.java

复制代码 代码如下:

package com.example.animtextview;

import android.content.context;
import android.content.res.typedarray;
import android.graphics.camera;
import android.graphics.matrix;
import android.util.attributeset;
import android.view.gravity;
import android.view.view;
import android.view.animation.accelerateinterpolator;
import android.view.animation.animation;
import android.view.animation.transformation;
import android.widget.textswitcher;
import android.widget.textview;
import android.widget.viewswitcher;

public class autotextview extends textswitcher implements
  viewswitcher.viewfactory {

 private float mheight;
 private context mcontext;
 //minup,moutup分离构成向下翻页的进出动画
 private rotate3danimation minup;
 private rotate3danimation moutup;

 //mindown,moutdown分离构成向下翻页的进出动画
 private rotate3danimation mindown;
 private rotate3danimation moutdown;

 public autotextview(context context) {
  this(context, null);
  // todo auto-generated constructor stub
 }

 public autotextview(context context, attributeset attrs) {
  super(context, attrs);
  // todo auto-generated constructor stub
  typedarray a = context.obtainstyledattributes(attrs, r.styleable.auto3d);
  mheight = a.getdimension(r.styleable.auto3d_textsize, 36);
  a.recycle();
  mcontext = context;
  init();
 }

 private void init() {
  // todo auto-generated method stub
  setfactory(this);
  minup = createanim(-90, 0 , true, true);
  moutup = createanim(0, 90, false, true);
  mindown = createanim(90, 0 , true , false);
  moutdown = createanim(0, -90, false, false);
  //textswitcher重要用于文件切换,比如 从文字a 切换到 文字 b,
  //setinanimation()后,a将执行inanimation,
  //setoutanimation()后,b将执行outanimation
        setinanimation(minup);
        setoutanimation(moutup);
 }

 private rotate3danimation createanim(float start, float end, boolean turnin, boolean turnup){
        final rotate3danimation rotation = new rotate3danimation(start, end, turnin, turnup);
        rotation.setduration(800);
        rotation.setfillafter(false);
        rotation.setinterpolator(new accelerateinterpolator());
        return rotation;
 }

 //这里返回的textview,就是我们看到的view
 @override
 public view makeview() {
  // todo auto-generated method stub
  textview t = new textview(mcontext);
  t.setgravity(gravity.center);
  t.settextsize(mheight);
  t.setmaxlines(2);
  return t;
 }
 //定义动作,向下滚动翻页
 public void previous(){
  if(getinanimation() != mindown){
   setinanimation(mindown);
  }
  if(getoutanimation() != moutdown){
   setoutanimation(moutdown);
  }
 }
 //定义动作,向上滚动翻页
 public void next(){
  if(getinanimation() != minup){
   setinanimation(minup);
  }
  if(getoutanimation() != moutup){
   setoutanimation(moutup);
  }
 }

  class rotate3danimation extends animation {
      private final float mfromdegrees;
      private final float mtodegrees;
      private float mcenterx;
      private float mcentery;
      private final boolean mturnin;
      private final boolean mturnup;
      private camera mcamera;

      public rotate3danimation(float fromdegrees, float todegrees, boolean turnin, boolean turnup) {
          mfromdegrees = fromdegrees;
          mtodegrees = todegrees;
          mturnin = turnin;
          mturnup = turnup;
      }

      @override
      public void initialize(int width, int height, int parentwidth, int parentheight) {
          super.initialize(width, height, parentwidth, parentheight);
          mcamera = new camera();
          mcentery = getheight() / 2;
          mcenterx = getwidth() / 2;
      }

      @override
      protected void applytransformation(float interpolatedtime, transformation t) {
          final float fromdegrees = mfromdegrees;
          float degrees = fromdegrees + ((mtodegrees - fromdegrees) * interpolatedtime);

          final float centerx = mcenterx ;
          final float centery = mcentery ;
          final camera camera = mcamera;
          final int derection = mturnup ? 1: -1;

          final matrix matrix = t.getmatrix();

          camera.save();
          if (mturnin) {
              camera.translate(0.0f, derection *mcentery * (interpolatedtime - 1.0f), 0.0f);
          } else {
              camera.translate(0.0f, derection *mcentery * (interpolatedtime), 0.0f);
          }
          camera.rotatex(degrees);
          camera.getmatrix(matrix);
          camera.restore();

          matrix.pretranslate(-centerx, -centery);
          matrix.posttranslate(centerx, centery);
      }
  }
}


2. mainactivity.java
复制代码 代码如下:

package com.example.animtextview;

import android.os.bundle;
import android.app.activity;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;

public class mainactivity extends activity implements onclicklistener {

 private button mbtnnext;
 private button mbtnprev;
 private autotextview mtextview02;
 private static int scount = 10;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  init();
 }
 private void init() {
  // todo auto-generated method stub
  mbtnnext = (button) findviewbyid(r.id.next);
  mbtnprev = (button) findviewbyid(r.id.prev);
  mtextview02 = (autotextview) findviewbyid(r.id.switcher02);
  mtextview02.settext("hello world!");
  mbtnprev.setonclicklistener(this);
  mbtnnext.setonclicklistener(this);
 }

 @override
 public void onclick(view arg0) {
  // todo auto-generated method stub
  switch (arg0.getid()) {
  case r.id.next:
   mtextview02.next();
   scount++;
   break;
  case r.id.prev:
   mtextview02.previous();
   scount--;
   break;
  }
  mtextview02.settext(scount%2==0 ?
    scount+"aafirstaa" :
    scount+"bbbbbbb");
  system.out.println("geth: ["+mtextview02.getheight()+"]");

 }
}

3. activity_main.xml

复制代码 代码如下:

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:auto3d="http://schemas.android.com/apk/res/com.example.animtextview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <relativelayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <button
            android:id="@+id/next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignparentleft="true"
            android:layout_alignparenttop="true"
            android:text="@string/next" />

        <button
            android:id="@+id/prev"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignparentright="true"
            android:layout_alignparenttop="true"
            android:text="@string/prev" />
    </relativelayout>

    <com.example.animtextview.autotextview
        android:id="@+id/switcher02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_green_dark"
        auto3d:textsize="30sp" />

</linearlayout>

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

三 小结
    我认为该控件实现的难点在于 动画文件的编写,即rotate3danimation中applytransformation(...)方法的实现,通过控制camara在y方向上挪动和在x方向上的旋转,从而造成上下翻滚的视觉感,然后将该值转换到matrix上,从而改变了参数(..,transformation t).有兴致的朋友可以直接改写该方法,便可失掉不同动画效果的textswitcher.