Android开发:TextView真正可控、不需要焦点的水平滚动--这才是真正的跑马灯

网上的TextView做跑马灯,大多都是要用到焦点,而且字数要超出滚动区域宽度才能实现滚动,使用起来十分不方便。

这里实现一种真正可控的滚动

(1)不需要焦点

(2)任意字数

(3)滚动从滚动区域右边出来,在左边消失,再从右边出来。

上代码

1、布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

   <Button 
       android:id="@+id/btn1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="改变滚动内容1"/>
      <Button 
       android:id="@+id/btn2"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_toRightOf="@id/btn1"
       android:text="改变滚动内容2"/>
       <Button 
       android:id="@+id/btn3"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_toRightOf="@id/btn2"
       android:text="退出程序"/>
        <com.using.margindemo.MarqueeTextView
        android:id="@+id/tvScroll"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40dp" >
    </com.using.margindemo.MarqueeTextView>
</RelativeLayout>

 

2、滚动控件

package com.using.margindemo;

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 MarqueeTextView extends TextView {

    /** 是否停止滚动 */
    private boolean mStopMarquee;
    private String mText;//文本内容
    private float mCoordinateX = 1280;//当前滚动位置
    private float mTextWidth;//文本宽度
    private int mScrollWidth = 1280;//滚动区域宽度
    private int speed = 1;//滚动速度
    public float getCurrentPosition() {
        return mCoordinateX;
    }

    public void setCurrentPosition(float mCoordinateX) {
        this.mCoordinateX = mCoordinateX;
    }

    public int getScrollWidth() {
        return mScrollWidth;
    }

    public void setScrollWidth(int mScrollWidth) {
        this.mScrollWidth = mScrollWidth;
    }

    public int getSpeed() {
        return speed;
    }

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

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

    public void setText(String text) {
        this.mText = text;
        mTextWidth = getPaint().measureText(mText);
        //mTextWidth = 1280;
        if (mHandler.hasMessages(0))
            mHandler.removeMessages(0);
        mHandler.sendEmptyMessageDelayed(0, 10);
    }


    @Override
    protected void onAttachedToWindow() {
        mStopMarquee = false;
        if (!isEmpty(mText))
            mHandler.sendEmptyMessageDelayed(0, 2000);
        super.onAttachedToWindow();
    }

    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    @Override
    protected void onDetachedFromWindow() {
        mStopMarquee = true;
        if (mHandler.hasMessages(0))
            mHandler.removeMessages(0);
        super.onDetachedFromWindow();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (!isEmpty(mText))
            canvas.drawText(mText, mCoordinateX, 150, getPaint());
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0:                    
                if (mCoordinateX < (-mTextWidth)) {//文字滚动完了,从滚动区域的右边出来
                    mCoordinateX = mScrollWidth;
                    invalidate();
                    if (!mStopMarquee) {
                    sendEmptyMessageDelayed(0, 500);
                    }
                } else {
                    mCoordinateX -= speed;
                    invalidate();
                    if (!mStopMarquee) {
                        sendEmptyMessageDelayed(0, 30);
                    }
                }

                break;
            }
            super.handleMessage(msg);
        }
    };

}

 

3、

package com.using.margindemo;

import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {
    private ImageView image;
    private MarqueeTextView marqueeTextView;
    private Button button1;
    private Button button2;
    private Button button3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题栏
        setContentView(R.layout.activity_main);        
        
        marqueeTextView = (MarqueeTextView)findViewById(R.id.tvScroll);        
        
        MarginLayoutParams margin1 = new MarginLayoutParams(
                marqueeTextView.getLayoutParams());
        margin1.setMargins(100, 200, 0, 0);//设置滚动区域位置:在左边距400像素,顶边距10像素的位置
        RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(margin1);
        layoutParams1.height = 240;//设滚动区域高度
        layoutParams1.width = 1000; //设置滚动区域宽度
        marqueeTextView.setLayoutParams(layoutParams1);                
        marqueeTextView.setScrollWidth(1000);
        marqueeTextView.setCurrentPosition(100 + 1000);//设置滚动信息从滚动区域的右边出来
        marqueeTextView.setSpeed(2);
        marqueeTextView.setText("这才是真正的跑马灯效果!");
        button1 = (Button)findViewById(R.id.btn1);
        button2 = (Button)findViewById(R.id.btn2);
        button3 = (Button)findViewById(R.id.btn3);        
        button1.setOnClickListener(new OnClickListener() {            
            @Override
            public void onClick(View v) {
                marqueeTextView.setText("这才是真正的跑马灯效果!");                
            }
        });
        
         button2.setOnClickListener(new OnClickListener() {            
            @Override
            public void onClick(View v) {
                marqueeTextView.setText("温馨提示:挂号或缴费后,请到休息区等候,我们会尽快为您服务,请留意屏幕叫号信息,谢谢!");
                
            }
        });
         button3.setOnClickListener(new OnClickListener() {            
             @Override
             public void onClick(View v) {
                 finish();
             }
         });
    }
}

 

 

Demo下载

 

posted @ 2014-12-16 09:47  tc310  阅读(6323)  评论(1编辑  收藏  举报