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

Android实现文字上下滚动效果

程序员文章站 2022-05-16 12:16:02
关于android实现文字上下滚动这个功能,我目前有两种方法实现: 一个是在textview 中加上翻转的动画效果,然后设置循环滚动;一种是改写viewpager...

关于android实现文字上下滚动这个功能,我目前有两种方法实现:

一个是在textview 中加上翻转的动画效果,然后设置循环滚动;一种是改写viewpager 的滚动方向,使它从下到上进行滚动,并设置循环滚动;

首先介绍第一种方法:

实现思路:自定义textview,在textview中加上从下到上滚动的动画效果,然后设置循环播放;

创建一个autotextview使之继承textview,然后在ondraw方法中调用getheight()方法获取textview当前的高度。
在接下来的动画翻转效果中,根据这个高度设置textview上下滚动的距离。下面是动画实现的方法:

/**
 * 向上脱离屏幕的动画效果
 */
private void animationstart() {
  objectanimator translate = objectanimator.offloat(this, "translationy", 0, -height);
  objectanimator alpha = objectanimator.offloat(this, "alpha", 1f, 0f);
  manimstart = new animatorset();
  manimstart.play(translate).with(alpha);
  manimstart.setduration(duration);
  manimstart.addlistener(this);

}

/**
 * 从屏幕下面向上的动画效果
 */
public void animationover() {
  objectanimator translate = objectanimator.offloat(this, "translationy", height, 0);
  objectanimator alpha = objectanimator.offloat(this, "alpha", 0f, 1f);
  manimover = new animatorset();
  manimover.play(translate).with(alpha);
  manimover.setduration(duration);

}

接下来实现objectanimator的监听事件,在onanimationend 调用settext方法,在动画没结束一次更新文字,并且继续执行动画效果

@override
public void onanimationend(animator animator) {
  super.settext(mtext);
  if (manimover == null) {
    animationover();

  }

  manimover.start();
}

然后调用一个可以设置循环滚动的类,这里可以使用scheduledexecutorservice,也可以使用 timer几设置计时滚动,在更新ui的时候,调用handler方法更新;

因为采用timer执行定时任务时只创建一个线程,所以这里建议采用scheduledexecutorservice;

/**
 * 获取数据并设置滚动播放
 * @param textview
 * @param list
 * @param autoplaytime
 */
public void gettextdata(final ideaautotextview textview, list<string> list, int autoplaytime) {
  this.textview = textview;
  this.textlist = list;

  if (autoplaytime != 0) {

    scheduledexecutorservice = executors.newsinglethreadscheduledexecutor();
    scheduledexecutorservice.schedulewithfixeddelay(new weaktimertask(this), autoplaytime, autoplaytime, timeunit.seconds);
  }
}


private timetaskhandler mhandler = new timetaskhandler(this);

private static class weaktimertask extends timertask {
  private weakreference<ideaautotextview> autotextreference;

  public weaktimertask(ideaautotextview mautotext) {
    this.autotextreference = new weakreference<>(mautotext);
  }

  @override
  public void run() {
    ideaautotextview autotext = autotextreference.get();
    if (autotext != null) {
      if (autotext.isshown()) {
        autotext.mhandler.sendemptymessage(0);
      }
    } else {
      cancel();
    }
  }
}

定时刷新频率较高,容易产生内存泄漏,这里采用弱引用避免这个情况发生

private final class timetaskhandler extends handler {
  private weakreference<ideaautotextview> autotextreference;

  public timetaskhandler(ideaautotextview autotext) {
    this.autotextreference = new weakreference<>(autotext);
  }

  @override
  public void handlemessage(message msg) {
    ideaautotextview autotext = autotextreference.get();

    if (autotext!=null)
    {
      /**
       * 设置当前文字
       */
      string text = textlist.get(index);
      index++;
      if (index > textlist.size() - 1) {
        index = 0;
      }
      textview.setautotext(text);
    }


  }
}

到此第一种方法介绍完毕。

第二种方法实现的原理和轮播图的原理类似,轮播图一般是左右横向滚动,这里需要把viewpager改成上下滑动,关于上下滑动的viewpager,可以在给github上找到;
其次轮播图中播放的是图片,把图片换成文字即可;
然后同样调用timer或者scheduledexecutorservice使viewpager自行滚动;
以下是代码:

package com.idea.idea.viewutils;

import android.content.context;
import android.os.handler;
import android.os.message;
import android.support.v4.view.pageradapter;
import android.support.v4.view.viewpager;
import android.util.attributeset;
import android.widget.relativelayout;

import java.lang.ref.weakreference;
import java.util.timertask;
import java.util.concurrent.executors;
import java.util.concurrent.scheduledexecutorservice;
import java.util.concurrent.timeunit;

/**
 * todo:修改viewpager方法实现文字滚动
 *
 * @author: create by qjj
 * @email: gxuqjj@163.com
 */
public class autoviewpager extends relativelayout{

  private verticalviewpager mverticalviewpager;
  private pageradapter madapter;
  private int autoplaytime;
  private scheduledexecutorservice scheduledexecutorservice;

  public autoviewpager(context context){
    this(context,null);
  }

  public autoviewpager(context context, attributeset attrs) {
    this(context, attrs, 0);

  }

  public autoviewpager(context context, attributeset attrs, int defstyle) {
    super(context, attrs, defstyle);
    initview();
  }


  /**
   * 初始化view
   */
  private void initview(){
    if(mverticalviewpager!=null){
      removeview(mverticalviewpager);
    }
    mverticalviewpager = new verticalviewpager(getcontext());
    mverticalviewpager.setlayoutparams(new layoutparams(layoutparams.match_parent, layoutparams.match_parent));
    addview(mverticalviewpager);

  }

  private final static class timetaskhandler extends handler {
    private weakreference<autoviewpager> mrollpagerviewweakreference;

    public timetaskhandler(autoviewpager autoviewpager) {
      this.mrollpagerviewweakreference = new weakreference<>(autoviewpager);
    }

    @override
    public void handlemessage(message msg) {
      autoviewpager autoviewpager = mrollpagerviewweakreference.get();
      int cur = autoviewpager.getviewpager().getcurrentitem()+1;
      if(cur>= autoviewpager.madapter.getcount()){
        cur=0;
      }
      autoviewpager.getviewpager().setcurrentitem(cur);

    }
  }
  private timetaskhandler mhandler = new timetaskhandler(this);

  private static class weaktimertask extends timertask {
    private weakreference<autoviewpager> mrollpagerviewweakreference;

    public weaktimertask(autoviewpager mautoviewpager) {
      this.mrollpagerviewweakreference = new weakreference<>(mautoviewpager);
    }

    @override
    public void run() {
      autoviewpager autoviewpager = mrollpagerviewweakreference.get();
      if (autoviewpager !=null){
        if(autoviewpager.isshown()){
          autoviewpager.mhandler.sendemptymessage(0);
        }
      }else{
        cancel();
      }
    }
  }

  /**
   * 开始滚动
   */
  private void autoplay(){
    if(autoplaytime<=0||madapter == null||madapter.getcount()<=1){
      return;
    }

    scheduledexecutorservice = executors.newsinglethreadscheduledexecutor();
    scheduledexecutorservice.schedulewithfixeddelay(new weaktimertask(this), autoplaytime, autoplaytime, timeunit.seconds);
  }

  public void setautotime(int autoplaytime){
    this.autoplaytime = autoplaytime;
    autoplay();
  }


  /**
   * viewpager
   * @return
   */
  public viewpager getviewpager() {
    return mverticalviewpager;
  }

  /**
   * 设置adapter
   * @param adapter
   */
  public void setadapter(pageradapter adapter){
    mverticalviewpager.setadapter(adapter);
    madapter = adapter;
    datachanged();
  }
  private void datachanged(){
    autoplay();
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。