ScrollTextView - scrolling TextView for Android

找了很就终于在国外一网站上找到一个Scroller的例子,为了日后方便查阅,在博客上记录以下。

Here are the source codes.

The key points are:

  • setHorizontallyScrolling() and use android.widget.Scroller to make the text scroll;
  • Use the attached TextPaint of the TextView to measure the length of the text in pixel;
  • setSingleLine() and setEllipsize(null) to make the text not wrapped and ellipsized;
  • Override computeScroll() to restart the scrolling when finished

Here are the source codes.

 

代码
/** ********************************************************************** */
package  com.dirtybear.android;

import  android.content.Context;
import  android.graphics.Rect;
import  android.text.TextPaint;
import  android.util.AttributeSet;
import  android.view.animation.LinearInterpolator;
import  android.widget.Scroller;
import  android.widget.TextView;

public   class  ScrollTextView  extends  TextView {

//  scrolling feature
private  Scroller mSlr;

//  milliseconds for a round of scrolling
private   int  mRndDuration  =   250 ;

//  the X offset when paused
private   int  mXPaused  =   0 ;

//  whether it's being paused
private   boolean  mPaused  =   true ;

/*
* constructor
*/
public  ScrollTextView(Context context) {
this (context,  null );
}

/*
* constructor
*/
public  ScrollTextView(Context context, AttributeSet attrs) {
this (context, attrs, android.R.attr.textViewStyle);
}

/*
* constructor
*/
public  ScrollTextView(Context context, AttributeSet attrs,  int  defStyle) {
super (context, attrs, defStyle);
//  customize the TextView
setSingleLine();
setEllipsize(
null );
setVisibility(INVISIBLE);
}

/**
* begin to scroll the text from the original position
*/
public   void  startScroll() {
//  begin from the very right side
mXPaused  =   - 1   *  getWidth();
//  assume it's paused
mPaused  =   true ;
resumeScroll();
}

/**
* resume the scroll from the pausing point
*/
public   void  resumeScroll() {

if  ( ! mPaused)
return ;

//  Do not know why it would not scroll sometimes
//  if setHorizontallyScrolling is called in constructor.
setHorizontallyScrolling( true );

//  use LinearInterpolator for steady scrolling
mSlr  =   new  Scroller( this .getContext(),  new  LinearInterpolator());
setScroller(mSlr);

int  scrollingLen  =  calculateScrollingLen();
int  distance  =  scrollingLen  -  (getWidth()  +  mXPaused);
int  duration  =  ( new  Double(mRndDuration  *  distance  *   1.00000
/  scrollingLen)).intValue();

setVisibility(VISIBLE);
mSlr.startScroll(mXPaused, 
0 , distance,  0 , duration);
mPaused 
=   false ;
}

/**
* calculate the scrolling length of the text in pixel
*
@return  the scrolling length in pixels
*/
private   int  calculateScrollingLen() {
TextPaint tp 
=  getPaint();
Rect rect 
=   new  Rect();
String strTxt 
=  getText().toString();
tp.getTextBounds(strTxt, 
0 , strTxt.length(), rect);
int  scrollingLen  =  rect.width()  +  getWidth();
rect 
=   null ;
return  scrollingLen;
}

/**
* pause scrolling the text
*/
public   void  pauseScroll() {
if  ( null   ==  mSlr)
return ;

if  (mPaused)
return ;

mPaused 
=   true ;

//  abortAnimation sets the current X to be the final X,
//  and sets isFinished to be true
//  so current position shall be saved
mXPaused  =  mSlr.getCurrX();

mSlr.abortAnimation();
}

@Override
/*
* override the computeScroll to restart scrolling when finished so as that
* the text is scrolled forever
*/
public   void  computeScroll() {
super .computeScroll();

if  ( null   ==  mSlr)  return ;

if  (mSlr.isFinished()  &&  ( ! mPaused)) {
this .startScroll();
}
}

public   int  getRndDuration() {
return  mRndDuration;
}

public   void  setRndDuration( int  duration) {
this .mRndDuration  =  duration;
}

public   boolean  isPaused() {
return  mPaused;
}
}
/** ********************************************************************** */


 
  

 

Issues to be fixed:

  1. Do not know why it would not scroll sometimes if setHorizontallyScrolling is called in constructor;
  2. The scrolling is not smooth enough. Maybe it's because of the single thread model of Android UI;

Tested on:


Windows XP


Android SDK 1.0 rc2


Android Emulator 1.0


Android Debug Bridge version 1.0.20

你可能感兴趣的:(textview)