Android实现文字上下滚动效果
关于Android实现文字上下滚动这个功能,我目前有两种方法实现:
一个是在TextView中加上翻转的动画效果,然后设置循环滚动;一种是改写ViewPager的滚动方向,使它从下到上进行滚动,并设置循环滚动;
首先介绍第一种方法:
实现思路:自定义TextView,在TextView中加上从下到上滚动的动画效果,然后设置循环播放;
创建一个AutoTextVieW使之继承TextView,然后在onDraw方法中调用getHeight()方法获取textview当前的高度。
在接下来的动画翻转效果中,根据这个高度设置TextView上下滚动的距离。下面是动画实现的方法:
/**
*向上脱离屏幕的动画效果
*/
privatevoidanimationStart(){
ObjectAnimatortranslate=ObjectAnimator.ofFloat(this,"translationY",0,-height);
ObjectAnimatoralpha=ObjectAnimator.ofFloat(this,"alpha",1f,0f);
mAnimStart=newAnimatorSet();
mAnimStart.play(translate).with(alpha);
mAnimStart.setDuration(DURATION);
mAnimStart.addListener(this);
}
/**
*从屏幕下面向上的动画效果
*/
publicvoidanimationOver(){
ObjectAnimatortranslate=ObjectAnimator.ofFloat(this,"translationY",height,0);
ObjectAnimatoralpha=ObjectAnimator.ofFloat(this,"alpha",0f,1f);
mAnimOver=newAnimatorSet();
mAnimOver.play(translate).with(alpha);
mAnimOver.setDuration(DURATION);
}
接下来实现ObjectAnimator的监听事件,在onAnimationEnd调用setText方法,在动画没结束一次更新文字,并且继续执行动画效果
@Override
publicvoidonAnimationEnd(Animatoranimator){
super.setText(mText);
if(mAnimOver==null){
animationOver();
}
mAnimOver.start();
}
然后调用一个可以设置循环滚动的类,这里可以使用ScheduledExecutorService,也可以使用Timer几设置计时滚动,在更新UI的时候,调用Handler方法更新;
因为采用Timer执行定时任务时只创建一个线程,所以这里建议采用ScheduledExecutorService;
/** *获取数据并设置滚动播放 *@paramtextView *@paramlist *@paramautoPlayTime */ publicvoidgetTextData(finalIdeaAutoTextviewtextView,Listlist,intautoPlayTime){ this.textView=textView; this.textList=list; if(autoPlayTime!=0){ scheduledExecutorService=Executors.newSingleThreadScheduledExecutor(); scheduledExecutorService.scheduleWithFixedDelay(newWeakTimerTask(this),autoPlayTime,autoPlayTime,TimeUnit.SECONDS); } } privateTimeTaskHandlermHandler=newTimeTaskHandler(this); privatestaticclassWeakTimerTaskextendsTimerTask{ privateWeakReference autoTextReference; publicWeakTimerTask(IdeaAutoTextviewmautoText){ this.autoTextReference=newWeakReference<>(mautoText); } @Override publicvoidrun(){ IdeaAutoTextviewautoText=autoTextReference.get(); if(autoText!=null){ if(autoText.isShown()){ autoText.mHandler.sendEmptyMessage(0); } }else{ cancel(); } } }
定时刷新频率较高,容易产生内存泄漏,这里采用弱引用避免这个情况发生
privatefinalclassTimeTaskHandlerextendsHandler{
privateWeakReferenceautoTextReference;
publicTimeTaskHandler(IdeaAutoTextviewautoText){
this.autoTextReference=newWeakReference<>(autoText);
}
@Override
publicvoidhandleMessage(Messagemsg){
IdeaAutoTextviewautoText=autoTextReference.get();
if(autoText!=null)
{
/**
*设置当前文字
*/
Stringtext=textList.get(index);
index++;
if(index>textList.size()-1){
index=0;
}
textView.setAutoText(text);
}
}
}
到此第一种方法介绍完毕。
第二种方法实现的原理和轮播图的原理类似,轮播图一般是左右横向滚动,这里需要把ViewPager改成上下滑动,关于上下滑动的viewpager,可以在给github上找到;
其次轮播图中播放的是图片,把图片换成文字即可;
然后同样调用Timer或者ScheduledExecutorService使ViewPager自行滚动;
以下是代码:
packagecom.idea.idea.viewutils;
importandroid.content.Context;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.support.v4.view.PagerAdapter;
importandroid.support.v4.view.ViewPager;
importandroid.util.AttributeSet;
importandroid.widget.RelativeLayout;
importjava.lang.ref.WeakReference;
importjava.util.TimerTask;
importjava.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
importjava.util.concurrent.TimeUnit;
/**
*todo:修改ViewPager方法实现文字滚动
*
*@author:Createbyqjj
*@email:gxuqjj@163.com
*/
publicclassAutoViewpagerextendsRelativeLayout{
privateVerticalViewPagermVerticalViewPager;
privatePagerAdaptermAdapter;
privateintautoPlayTime;
privateScheduledExecutorServicescheduledExecutorService;
publicAutoViewpager(Contextcontext){
this(context,null);
}
publicAutoViewpager(Contextcontext,AttributeSetattrs){
this(context,attrs,0);
}
publicAutoViewpager(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
initView();
}
/**
*初始化view
*/
privatevoidinitView(){
if(mVerticalViewPager!=null){
removeView(mVerticalViewPager);
}
mVerticalViewPager=newVerticalViewPager(getContext());
mVerticalViewPager.setLayoutParams(newLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
addView(mVerticalViewPager);
}
privatefinalstaticclassTimeTaskHandlerextendsHandler{
privateWeakReferencemRollPagerViewWeakReference;
publicTimeTaskHandler(AutoViewpagerautoViewpager){
this.mRollPagerViewWeakReference=newWeakReference<>(autoViewpager);
}
@Override
publicvoidhandleMessage(Messagemsg){
AutoViewpagerautoViewpager=mRollPagerViewWeakReference.get();
intcur=autoViewpager.getViewPager().getCurrentItem()+1;
if(cur>=autoViewpager.mAdapter.getCount()){
cur=0;
}
autoViewpager.getViewPager().setCurrentItem(cur);
}
}
privateTimeTaskHandlermHandler=newTimeTaskHandler(this);
privatestaticclassWeakTimerTaskextendsTimerTask{
privateWeakReferencemRollPagerViewWeakReference;
publicWeakTimerTask(AutoViewpagermAutoViewpager){
this.mRollPagerViewWeakReference=newWeakReference<>(mAutoViewpager);
}
@Override
publicvoidrun(){
AutoViewpagerautoViewpager=mRollPagerViewWeakReference.get();
if(autoViewpager!=null){
if(autoViewpager.isShown()){
autoViewpager.mHandler.sendEmptyMessage(0);
}
}else{
cancel();
}
}
}
/**
*开始滚动
*/
privatevoidautoPlay(){
if(autoPlayTime<=0||mAdapter==null||mAdapter.getCount()<=1){
return;
}
scheduledExecutorService=Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(newWeakTimerTask(this),autoPlayTime,autoPlayTime,TimeUnit.SECONDS);
}
publicvoidsetAutoTime(intautoPlayTime){
this.autoPlayTime=autoPlayTime;
autoPlay();
}
/**
*viewpager
*@return
*/
publicViewPagergetViewPager(){
returnmVerticalViewPager;
}
/**
*设置Adapter
*@paramadapter
*/
publicvoidsetAdapter(PagerAdapteradapter){
mVerticalViewPager.setAdapter(adapter);
mAdapter=adapter;
dataChanged();
}
privatevoiddataChanged(){
autoPlay();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。