效果图:

android怎样写一个循环文字滚动的TextView_初始化

在layout中这样来声明:

<com.kaixin001.view.ScrollText android:id="@+id/news_statustxt" 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_gravity="center_vertical"
android:textColor="#000000"
android:textSize="16sp"
android:hint="@string/news_state_hint"
android:inputType="text"/>


activity这样来调用:

private void initStatus(){
ivState = (ImageView) findViewById(R.id.news_statusinput);
//必须使text长度比控件的宽度大
String s = "dsafsdfsdf(#开心)fsgfdg(#闭嘴)fdgdfgdfgdfgdfgdfgfdgfdgfdgfdgdfg";
newsModel.setStatus(s);
String strModel = newsModel.getStatus();
setStateText(strModel);

}

private void setStateText(String strModel){
if(!TextUtils.isEmpty(strModel)){
tvState.setStateList(newsModel.getStateList());
tvState.setText(strModel);
tvState.init(getWindowManager(), handler);
tvState.startScroll();
tvState.start();
}
}
<pre name="code" class="java"> <span style="white-space:pre"> </span> public void setStatus(String status){
this.status = status;
if(!TextUtils.isEmpty(status)){
stateList = ParseNewsInfoUtil.parseStr(status);
}
<span style="white-space:pre"> </span>}


private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case ScrollText.TEXT_TIMER:if(tvState != null){tvState.scrollText();}break;default:break;}}};

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.WindowManager;
import android.widget.TextView;
import com.kaixin001.item.LinkInfo;
import com.kaixin001.model.StateFaceModel;

public class ScrollText extends TextView {

public static final int TEXT_TIMER = 100;
private float textLength = 0f;// 文本长度
private float viewWidth = 0f;
private float step = 0f;// 文字的横坐标
private float y = 0f;// 文字的纵坐标
private float temp_view_plus_text_length = 0.0f;// 用于计算的暂时变量
private float temp_view_plus_two_text_length = 0.0f;// 用于计算的暂时变量
private boolean isStarting = false;// 是否開始滚动
private int left = 0;
private int right = 0;
private Paint paint = null;// 画图样式
private String text = "";// 文本内容
private Bitmap txtBmp;
private Canvas txtCanvas;
private FontMetrics fontMetrics;
private Timer timer = new Timer();
private ArrayList<LinkInfo> stateList;

Handler handler;

TimerTask task = new TimerTask() {
public void run() {
if (handler != null && isStarting) {
Message msg = Message.obtain();
msg.what = TEXT_TIMER;
handler.sendMessage(msg);
}
}
};

public ScrollText(Context context) {
super(context);
}

public ScrollText(Context context, AttributeSet attrs) {
super(context, attrs);
}

public ScrollText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

/** */
/**
* 文本初始化,每次更改文本内容或者文本效果等之后都须要又一次初始化一下
*/
public void init(WindowManager windowManager, Handler handler) {
try {
this.handler = handler;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);
paint.setTextSize(getTextSize());
paint.setColor(getCurrentTextColor());
text = getText().toString();
textLength = 0;
// textLength = paint.measureText(text);
int len = stateList.size();
for (int i = 0; i < len; i++) {
LinkInfo info = stateList.get(i);
if (info.isFace()) {// 表情符排版
Bitmap faceBmp = StateFaceModel.getInstance()
.getSmallFaceIcon(info.getContent());
int xLen = faceBmp.getWidth();
textLength += xLen + 4;
continue;
}
String strContent = info.getContent();
float xLen = paint.measureText(strContent);
textLength += xLen;
}
left = this.getPaddingLeft();
right = this.getPaddingRight();
step = textLength;
fontMetrics = paint.getFontMetrics();

y = getPaddingTop();// getTextSize() + getPaddingTop();
txtBmp = null;
} catch (Exception ex) {
ex.printStackTrace();
}
}

public void scrollText() {
if (!isStarting) {
return;
}
invalidate();
if (viewWidth < textLength) {
step += 0.5;
if (step > temp_view_plus_two_text_length) {
step = textLength;
}
}
}

public void setStateList(ArrayList<LinkInfo> stateList) {
this.stateList = stateList;
}

private void setTxtBmp() {
if (txtBmp == null && fontMetrics != null) {
y = -paint.ascent();// fontMetrics.bottom -
// fontMetrics.ascent;//(this.getHeight() -
// (int)fontMetrics.ascent)/2;
viewWidth = getWidth() - left - right;
temp_view_plus_text_length = viewWidth + textLength;
temp_view_plus_two_text_length = viewWidth + textLength * 2;
txtCanvas = new Canvas();

int width = (int) viewWidth;
float height = getHeight();
txtBmp = Bitmap.createBitmap(width, (int) height, Config.ARGB_8888);
txtCanvas.setBitmap(txtBmp);

}
}

/** */
/**
* 開始滚动
*/
public void startScroll() {
isStarting = true;
}

/** */
/**
* 停止滚动
*/
public void stopScroll() {
isStarting = false;
// invalidate();
}

public void start() {
timer.schedule(task, 10, 20);
}

public void stop() {
timer.cancel();
}

@Override
public void onDraw(Canvas canvas) {
try {
setTxtBmp();
if (txtBmp == null) {
return;
}
Paint txtPaint = new Paint();
txtPaint.setColor(Color.WHITE);
txtPaint.setStyle(Style.FILL);
txtCanvas.drawRect(0, 0, txtBmp.getWidth(), txtBmp.getHeight(),
txtPaint);
txtPaint.setAntiAlias(true);
txtPaint.setStyle(Style.STROKE);
txtPaint.setTextSize(getTextSize());
txtPaint.setColor(getCurrentTextColor());
float x = 0;
// step为text的宽度
if (viewWidth < textLength) {
x = temp_view_plus_text_length - step;
}
int len = stateList.size();
float curLen = x;
for (int i = 0; i < len; i++) {
LinkInfo info = stateList.get(i);
if (info.isFace()) {// 表情符排版
Bitmap faceBmp = StateFaceModel.getInstance()
.getSmallFaceIcon(info.getContent());
int xLen = faceBmp.getWidth();
txtCanvas.drawBitmap(faceBmp, curLen + 2, 0, txtPaint);
curLen += xLen + 4;
continue;
}
String strContent = info.getContent();
strContent = strContent.replaceAll("\n", " ");
float xLen = txtPaint.measureText(strContent);
//由于x的值一直降低,所以文字能够滚动
txtCanvas.drawText(strContent, curLen, y, txtPaint); //<span style="font-family: Arial, Helvetica, sans-serif;">txtCanvas早drawtext.txtBmp上也自然也带有这些text</span>

curLen += xLen;
}
canvas.drawBitmap(txtBmp, left, 0, paint);
} catch (Exception ex) {
ex.printStackTrace();
}
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
txtBmp = null;
setTxtBmp();
}
}