解决方案 »

  1.   

    代码也贴上。package com.example.myscroltextview.view;import java.util.ArrayList;import android.content.Context;
    import android.graphics.Canvas;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.widget.TextView;public class MyScrollTextView extends TextView {
    private ArrayList<String> lineStrings;// 每行的字符串
    private String scrollText = "";// 要显示的text

    private Handler handler;// 处理滚动消息
    private int exactlyWidth = -1;// 真实宽度,在配置width="xxdp"里起作用
    private int exactlyHeight = -1;// 真实高度,在配置height="xxdip"里起作用

    private float currentY;// 当前的位移
    private float absloutHeight = 0;// 实际高度:所有字显示完全需要的高度
    private float speed = 2f;// 每次滚动的距离
    private int delayTime = 1;// handler发消息的时间间隔

    private boolean needStop;// 为true代表原来是滚动
    private boolean scrolling = false;// 是否在滚动
    public  boolean isUp = true;//是否是向上的方向。 public MyScrollTextView(Context context, AttributeSet attrs) {
    super(context, attrs); init();
    } public MyScrollTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
    } public MyScrollTextView(Context context) {
    super(context);
    init();
    } public String getScrollText() {
    return scrollText;
    } public void setScrollText(String scrollText) {
    this.scrollText = scrollText;
    reset();
    } private void reset() {// 重置
    System.out.println("----reset() start currentY=" + currentY);
    requestLayout();
    invalidate();
    //currentY = 0;
    System.out.println("----reset() end currentY=" + currentY); }

    public void pause() {
    if (scrolling) {
    stop();
    needStop = true;
    }
    } public void goOn() {
    if (needStop) {
    play();
    needStop = false;
    }
    } private void init() {// 初始化
    handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
    System.out.println("--------------handleMessage -- absloutHeight=" + absloutHeight + 
    "   getHeight=" + getHeight() + " currentY=" + currentY + 
    " msg.what=" +msg.what);
    if (absloutHeight <= getHeight()) {
    currentY = 0;
    stop();
    return;
    }
    switch (msg.what) {
    case 0: {
    if(isUp){
    currentY = currentY - speed;
    }else{
    currentY = currentY + speed;
    }

    resetCurrentY();
    invalidate();
    handler.sendEmptyMessageDelayed(0, delayTime);
    break;
    }
    case 1: {
    currentY += msg.arg1;

    resetCurrentY();
    invalidate();
    }
    } } /**
     * 重置currentY(当currentY超过absloutHeight时,让它重置为0)
     */
    private void resetCurrentY() {
    System.out.println("----resetCurrentY()");
    if (currentY >= absloutHeight || currentY <= -absloutHeight || getHeight() <= 0) {
    //currentY = 0;
    } }
    }; } /**
     * 更改滚动状态
     */
    public void updateScrollStatus() {
    if (scrolling) {
    stop();
    } else {
    play();
    }
    } /**
     * 开始滚动
     */
    public void play() {
    if (!scrolling) {
    handler.sendEmptyMessage(0);
    scrolling = true;
    }
    } /**
     * 停止滚动
     */
    public void stop() {
    if (scrolling) {
    handler.removeMessages(0);
    scrolling = false;
    }
    } @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //currentY = currentYRecorder;
    System.out.println("------------onMeasure-" + " currentY="+currentY);
    int width = MeasureWidth(widthMeasureSpec);
    System.out.println("------------onMeasure--MeasureWidth() after" + " currentY="+currentY);
    int height = MeasureHeight(width, heightMeasureSpec);
    System.out.println("------------onMeasure--MeasureHeight() after" + " currentY="+currentY);
    setMeasuredDimension(width, height);
    System.out.println("------------onMeasure--setMeasuredDimension() after" + " currentY="+currentY);
    //currentY = 0;
    System.out.println("------------onMeasure--height=" + height + " absloutHeight="+absloutHeight);
    if (height < absloutHeight) {
    System.out.println("------play()");
    play();
    } else {
        stop();
        System.out.println("------stop()");
    }

    //currentY = currentYRecorder; } /**
     * 测量宽度
     * 
     * @param widthMeasureSpec
     * @return
     */
    private int MeasureWidth(int widthMeasureSpec) {
    int mode = MeasureSpec.getMode(widthMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    // 如果是wrap_content
    if (mode == MeasureSpec.AT_MOST) {
    double abwidth = getPaint().measureText(scrollText);
    width = Math.min((int) Math.rint(abwidth), width);
    exactlyWidth = -1;
    }
    if (mode == MeasureSpec.EXACTLY) {
    exactlyWidth = width;
    }
    return width;
    } /**
     * 测量高度
     * 
     * @param width
     *            :宽度
     * @param heightMeasureSpec
     * @return
     */
    private int MeasureHeight(int width, int heightMeasureSpec) {
    int mode = MeasureSpec.getMode(heightMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    generateTextList(width);
    int lines = lineStrings.size(); absloutHeight = lines * getLineHeight() + getPaddingBottom()
    + getPaddingTop();
    // 如果是wrap_content
    if (mode == MeasureSpec.AT_MOST) {
    height = (int) Math.min(absloutHeight, height);
    exactlyHeight = -1;
    } else if (mode == MeasureSpec.EXACTLY) {
    exactlyHeight = height;
    }
    return height;
    } /**
     * 是否为英文单词的首字母
     * 
     * @param str
     * @param i
     * @return
     */
    boolean isENWordStart(String str, int i) {
    if (i == 0) {
    return true; } else if (str.charAt(i - 1) == ' ') {
    return true;
    }
    return false;
    } /**
     * 获取一行的字符
     * 
     * @param MaxWidth
     * @param str
     * @return
     */
    private String getLineText(int MaxWidth, String str) { // 真实行
    StringBuffer trueStringBuffer = new StringBuffer();
    // 临时行
    StringBuffer tempStringBuffer = new StringBuffer(); for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);
    String add = "";
    // 如果c是字母需要考虑英文单词换行功能
    if (!isChinese(c) && isENWordStart(str, i)) { int place = getNextSpecePlace(i, str);
    // 找到下一个空格
    if (place > -1) {
    add = str.substring(i, place) + " ";
    if (getPaint().measureText(add) > MaxWidth) {
    add = "" + c;
    } else {
    i = place;
    }
    } else {
    add = "" + c;
    }
    } else {
    add = "" + c;
    } tempStringBuffer.append(add);
    String temp = tempStringBuffer.toString();
    float width = getPaint().measureText(temp.toString()); if (width <= MaxWidth) { trueStringBuffer.append(add);
    } else {
    break;
    } } return trueStringBuffer.toString();
    } /**
     * 找到下一个空格的地方
     * 
     * @param i
     * @param str
     * @return
     */
    int getNextSpecePlace(int i, String str) {
    for (int j = i; j < str.length(); j++) {
    char c = str.charAt(j);
    if (c == ' ') {
    return j;
    }
    }
    return -1;
    } /**
     * 生成多行字符串列表
     * 
     * @param MaxWidth
     */
    public void generateTextList(int MaxWidth) {
    lineStrings = new ArrayList<String>();
    String remain = scrollText; while (!remain.equals("")) {
    String line = getLineText(MaxWidth, remain);
    lineStrings.add(line);
    remain = remain.substring(line.length(), remain.length());
    }
    }; @Override
    protected void onDraw(Canvas canvas) {
    //currentYRecorder = currentY;
    System.out.println("------------onDraw--"   + " currentY="+currentY+ " exactlyHeight=" + exactlyHeight + " absloutHeight" + absloutHeight + "");
    super.onDraw(canvas);
    float x = getPaddingLeft();
    float y = getPaddingTop(); float lineHeight = getLineHeight();
    float textSize = getPaint().getTextSize(); for (int i = 0; i < lineStrings.size(); i++) {
    y = lineHeight * i + textSize + currentY; float min = 0;
    if (exactlyHeight > -1) {
    min = Math.min(min, exactlyHeight - absloutHeight);
    }
    if (y < min) { y = y + absloutHeight; } else if (y >= min && y < textSize + min) { // 如果最顶端的文字已经到达需要循环从下面滚出的时候
    canvas.drawText(lineStrings.get(i), x, y + absloutHeight,
    getPaint());
    }
    if (y >= absloutHeight) {
    // 如果最底端的文字已经到达需要循环从上面滚出的时候
    canvas.drawText(lineStrings.get(i), x, y, getPaint());
    //y = y - absloutHeight;
    y = y + absloutHeight;
    }

    //System.out.println("------------onDraw--for drawText before"   + " currentY="+currentY+ " exactlyHeight=" + exactlyHeight + " absloutHeight" + absloutHeight + ""); canvas.drawText(lineStrings.get(i), x, y, getPaint());

    //System.out.println("------------onDraw--for drawText after"   + " currentY="+currentY+ " exactlyHeight=" + exactlyHeight + " absloutHeight" + absloutHeight + ""); }
    } /**
     * 判断是否为中文
     * 
     * @param c
     * @return
     */
    private static final boolean isChinese(char c) {
    Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
    if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
    || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
    || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
    || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
    || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
    return true;
    }
    return false;
    }}
      

  2.   

    package com.example.myscroltextview;import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.Timer;
    import java.util.TimerTask;import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;import com.example.myscroltextview.view.MyScrollTextView;public class MyMainActivity extends Activity {
    private MyScrollTextView ball1, ball2, ball3, ball4, ball5, ball6, ball7;
    private Button changeButton;
    private TimerTask task;
    private Timer timer = new Timer(); private final Boolean[] isUp = {false, true};
    private int time; @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_activity_main); ball1 = (MyScrollTextView) findViewById(R.id.myscroll1);
    ball2 = (MyScrollTextView) findViewById(R.id.myscroll2);
    ball3 = (MyScrollTextView) findViewById(R.id.myscroll3);
    ball4 = (MyScrollTextView) findViewById(R.id.myscroll4);
    ball5 = (MyScrollTextView) findViewById(R.id.myscroll5);
    ball6 = (MyScrollTextView) findViewById(R.id.myscroll6);
    ball7 = (MyScrollTextView) findViewById(R.id.myscroll7);
    changeButton = (Button) findViewById(R.id.my_button_update); // final List<String> strs = new ArrayList<String>();
    // strs.add("xx01\t02\t03\t04\t05\t06\t07\t08\t09\t10\t11\t12\t13\t14\t15\t16\t17\t18\t19\t20\t21\t22\t23\t24\t25\t26\t27\t28\t29\t30\t31\t32\t33\t34\t35");
    // strs.add("yy01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35");
    final List<String> ssqRed = new ArrayList<String>();
    //ssqRed.add("01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33");
    ssqRed.add("0102030405060708091011121314151617181920212223242526272829303132333"); final List<String> ssqBlue = new ArrayList<String>();
    ssqBlue.add("01020304050607080910111213141516"); final List<String> dltRed = new ArrayList<String>();
    dltRed.add("0102030405060708091011121314151617181920212223242526272829303132333435"); final List<String> dltBlue = new ArrayList<String>();
    dltBlue.add("010203040506070809101112"); changeButton.setOnClickListener(new View.OnClickListener() { @Override
    public void onClick(View v) {
    ball1.setText("");
    /*ball2.setText("");
    ball3.setText("");
    ball4.setText("");
    ball5.setText("");
    ball6.setText("");
    ball7.setText("");*/

    time = 300;
    task = new TimerTask() {
    @Override
    public void run() {
    runOnUiThread(new Runnable() { // UI thread
    @Override
    public void run() {
    time--;

    if (time <= 0) {
    ball1.stop();
    /*ball2.stop();
    ball3.stop();
    ball4.stop();
    ball5.stop();
    ball6.stop();
    ball7.stop();*/

    ball1.setScrollText("");
    /*ball2.setScrollText("");
    ball3.setScrollText("");
    ball4.setScrollText("");
    ball5.setScrollText("");
    ball6.setScrollText("");
    ball7.setScrollText("");*/

    ball1.setText("02");
    /*ball2.setText("06");
    ball3.setText("24");
    ball4.setText("06");
    ball5.setText("14");
    ball6.setText("27");
    ball7.setText("11");*/
    task.cancel();
    } else {
    int i = (int) (ssqRed.size() * Math.random());
    ball1.setScrollText(ssqRed.get(i));
    /*ball2.setScrollText(ssqRed.get(i));
    ball3.setScrollText(ssqRed.get(i));
    ball4.setScrollText(ssqRed.get(i));
    ball5.setScrollText(ssqRed.get(i));
    ball6.setScrollText(ssqRed.get(i));
    ball7.setScrollText(ssqBlue.get(i));*/ Random random = new Random();
    // random.nextInt(2); // [0,2) ball1.isUp = isUp[random.nextInt(2)];
    /*ball2.isUp = isUp[random.nextInt(2)];
    ball3.isUp = isUp[random.nextInt(2)];
    ball4.isUp = isUp[random.nextInt(2)];
    ball5.isUp = isUp[random.nextInt(2)];
    ball6.isUp = isUp[random.nextInt(2)];
    ball7.isUp = isUp[random.nextInt(2)];*/
    }
    }
    });
    }
    };
    timer.schedule(task, 0, 1000);
    }
    }); }}