• 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下载

  • 相关阅读:
    Phonon
    qt 的mysql的库
    vwmare下安装fedora
    C++标准库
    C#命名空间
    用谷歌Chrome浏览器来当手机模拟器
    Javascript实现ECMAScript 5中的map、reduce和filter函数
    页面变灰实现方案
    jQuery检查元素是否在视口内(屏幕可见区域内)
    兼容浏览器的获取指定元素(elem)的样式属性(name)的方法
  • 原文地址:https://www.cnblogs.com/tc310/p/4166419.html
Copyright © 2020-2023  润新知