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{ privateWeakReference mRollPagerViewWeakReference; 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(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。