android TextView 垂直自動滾動

webphp 12年前發布 | 2K 次閱讀 html5未來

在做android 應用的開發的時候,橫向滾動或者要做出跑馬燈的效果很簡單,textview本身的屬性就支持,只要設置準確就會滾動,開發起來比較簡單,但是textview 不支持垂直滾動,那么垂直滾動就需要自己來實現了,很多網友提供的垂直滾 動方案都是千篇一律,使用ScrollView來進行滾動,但是都不完美,做起來有些別扭。有一位網友給出的歌詞的滾動思路明確,能從根本上解決問題,因此我實現的這個滾動是在這位網友的基礎上實現,封裝了一個View,view繼承自TextView。先看看實現的效果:

實現圖中效果的關鍵點是:

1、重寫onDrow方法,計算每次的滾動的距離。

2、計算view的Y軸的重點,讓當前顯示的處于高亮顯示狀態。

3、定時的刷新View使其界面不斷的刷先,出現滾動的效果。

4、實現數據結構,將數據傳給view。

下面看看主要代碼:

1、創建一個類繼承TextView

/**
 * @author xushilin
 * 
 * 垂直滾動的TextView Widget
 */ public class VerticalScrollTextView extends TextView

 

2、實現構造函數:

public VerticalScrollTextView(Context context) {
        super(context);
        init();
    }
    public VerticalScrollTextView(Context context, AttributeSet attr) {
        super(context, attr);
        init();
    }
    public VerticalScrollTextView(Context context, AttributeSet attr, int i) {
        super(context, attr, i);
        init();
    }
    private void init() {
        setFocusable(true);
        //這里主要處理如果沒有傳入內容顯示的默認值      if(list==null){
            list=new ArrayList<Notice>();
            Notice sen=new Notice(0,"暫時沒有通知公告");
            list.add(0, sen);
        }       
        //普通文字的字號,以及畫筆顏色的設置         mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(16);
        mPaint.setColor(Color.BLACK);
        mPaint.setTypeface(Typeface.SERIF);     
        //高亮文字的字號,以及畫筆顏色的設置         mPathPaint = new Paint();
        mPathPaint.setAntiAlias(true);
        mPathPaint.setColor(Color.RED);
        mPathPaint.setTextSize(16);
        mPathPaint.setTypeface(Typeface.SANS_SERIF);
    }

 

3、從寫onDraw方法,并計算文字的行距,并且將將普通文字和高亮文字,在這個方法中繪制出來

protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(0xEFeffff);
        Paint p = mPaint;
        Paint p2 = mPathPaint;
        p.setTextAlign(Paint.Align.CENTER);
        if (index == -1)
            return;
        p2.setTextAlign(Paint.Align.CENTER);

        canvas.drawText(list.get(index).getName(), mX, middleY, p2);
        float tempY = middleY;

        for (int i = index - 1; i >= 0; i--) {           
            tempY = tempY - DY;
            if (tempY < 0) {
                break;
            }
            canvas.drawText(list.get(i).getName(), mX, tempY, p);           
        }
        tempY = middleY;

        for (int i = index + 1; i < list.size(); i++) {          
            tempY = tempY + DY;
            if (tempY > mY) {
                break;
            }
            canvas.drawText(list.get(i).getName(), mX, tempY, p);           
        }
    }

4、計算Y軸中值以及更新索引

protected void onSizeChanged(int w, int h, int ow, int oh) {
        super.onSizeChanged(w, h, ow, oh);
        mX = w * 0.5f; 
        mY = h;
        middleY = h * 0.5f;
    }

    private long updateIndex(int index) {   
        if (index == -1)
            return -1;
        this.index=index;       
        return index;
    }

 

5、定時更新view,并將接口暴露給客戶程序調用。

public void updateUI(){
        new Thread(new updateThread()).start();
    }

    class updateThread implements Runnable {
        long time = 1000;
        int i=0;
        public void run() {
            while (true) {
                long sleeptime = updateIndex(i);
                time += sleeptime;
                mHandler.post(mUpdateResults);
                if (sleeptime == -1)
                    return;
                try {
                    Thread.sleep(time);
                    i++;
                    if(i==getList().size())
                        i=0;
                } catch (InterruptedException e) {                  
                    e.printStackTrace();
                }
            }
        }
    }
    Handler mHandler = new Handler();
    Runnable mUpdateResults = new Runnable() {
        public void run() {
            invalidate(); 
        }
    };

 

6、xml布局文件中調用:

<?xml version="1.0" encoding="utf-8"?>   <!-- Demonstrates scrolling with a ScrollView. -->   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical">     <com.demo.xsl.text.SampleView      
        android:id="@+id/sampleView1"         android:layout_width="fill_parent"         android:layout_height="fill_parent"         android:background="@drawable/selector"        />    </LinearLayout>

7、java代碼中調用,傳遞數據:

package com.demo.xsl.text;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.os.Handler;public class VerticalScrollTextActivity extends Activity {


    SampleView mSampleView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mSampleView = (SampleView) findViewById(R.id.sampleView1);
        List lst=new ArrayList<Sentence>();
        for(int i=0;i<30;i++){
            if(i%2==0){
                Sentence sen=new Sentence(i,i+"、金球獎三甲揭曉 C羅梅西哈維入圍 ");
                lst.add(i, sen);
            }else{
                Sentence sen=new Sentence(i,i+"、公牛欲用三大主力換魔獸????");
                lst.add(i, sen);
            }
        }   
        //給View傳遞數據         mSampleView.setList(lst);
        //更新View        mSampleView.updateUI();     
    }   
}


作者:藍之風
出處:http://www.cnblogs.com/vaiyanzi/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

 本文由用戶 webphp 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!