2012年10月15日 星期一

Android TextView跑馬燈特效

原生TextView本身就有跑馬燈特效,但限制多多:文長得超過顯示區域,一定要在得到焦點的情形;再加上又不能調速,根本就不實用,所以也就寫一個簡單的跑馬燈。

作法很簡單,繼承原本的TextView重新實作onDraw即可。之後把原本的TextView 改成自己定義的名稱即可,在layout中使用 com.example.views.MarqueeTextView就可以了。
要注意的是:在onCreate中宣告後建立可能會得不到元件寬度,所以在onDraw時,才做確定寬度較好。



package com.example.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

public class MarqueeTextView extends TextView
{

    private float textLength = 0f; // 文長

    private float viewWidth = 0f; // 顯示寬度

    private float step = 0f; // 文字的橫座標

    private float speed = 1.5f; // 速度

    private float y = 0f; // 文字的縱座標

    private float start_point = 0.0f; // 起點

    private float run_length = 0.0f; // 移動距離

    private Paint paint = null;

    private String text = "";

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

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

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

    public void setSpeed(float speed)
    {
        this.speed = speed;
    }

    private void init()
    {
        paint = getPaint();
        text = getText().toString();
        textLength = paint.measureText(text);
        viewWidth = getWidth();
        step = textLength;
        start_point = viewWidth + textLength;
        run_length = viewWidth + textLength * 2;
        y = getTextSize() + getPaddingTop();
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        if (viewWidth == 0) {
            init();
        }
        canvas.drawText(text, start_point - step, y, paint);
        step += speed;
        if (step > run_length)
            step = textLength;
        invalidate();
    }
}