博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不依赖焦点和选中的TextView跑马灯
阅读量:4206 次
发布时间:2019-05-26

本文共 4818 字,大约阅读时间需要 16 分钟。

前言

继承TextView,并仿照源码修改而来,主要是取消了焦点和选中了判断,也不依赖文本的宽度。

 

声明
欢迎转载,但请保留文章原始出处:) 
博客园:http://www.cnblogs.com

农民伯伯: http://over140.cnblogs.com 

 

正文

import java.lang.ref.WeakReference;
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 Marquee mMarquee;
    
public MarqueeTextView(Context context, AttributeSet attrs) {
        
super(context, attrs);
    }
    
public MarqueeTextView(Context context, AttributeSet attrs, 
int defStyle) {
        
super(context, attrs, defStyle);
    }
    
public MarqueeTextView(Context context) {
        
super(context);
    }
    
public 
void startMarquee() {
        startMarquee(-1);
    }
    
public 
void startMarquee(
int repeatLimit) {
        
if (mMarquee == 
null)
            mMarquee = 
new Marquee(
this);
        mMarquee.start(repeatLimit);
    }
    
public 
void stopMarquee() {
        
if (mMarquee != 
null && !mMarquee.isStopped()) {
            mMarquee.stop();
        }
    }
    
public 
void toggleMarquee() {
        
if (mMarquee == 
null || mMarquee.isStopped())
            startMarquee();
        
else
            stopMarquee();
    }
    @Override
    
protected 
void onDraw(Canvas canvas) {
        
if (mMarquee != 
null && mMarquee.isRunning()) {
            
final 
float dx = -mMarquee.getScroll();
            canvas.translate(getLayoutDirection() == LAYOUT_DIRECTION_RTL ? -dx
                    : +dx, 0.0f);
        }
        
super.onDraw(canvas);
    }
    @SuppressWarnings("unused")
    
private 
static 
final 
class Marquee 
extends Handler {
        
//
 TODO: Add an option to configure this
        
private 
static 
final 
float MARQUEE_DELTA_MAX = 0.07f;
        
private 
static 
final 
int MARQUEE_DELAY = 0;
//
 1200;
        
private 
static 
final 
int MARQUEE_RESTART_DELAY = 1200;
        
private 
static 
final 
int MARQUEE_RESOLUTION = 1000 / 30;
        
private 
static 
final 
int MARQUEE_PIXELS_PER_SECOND = 30;
        
private 
static 
final 
byte MARQUEE_STOPPED = 0x0;
        
private 
static 
final 
byte MARQUEE_STARTING = 0x1;
        
private 
static 
final 
byte MARQUEE_RUNNING = 0x2;
        
private 
static 
final 
int MESSAGE_START = 0x1;
        
private 
static 
final 
int MESSAGE_TICK = 0x2;
        
private 
static 
final 
int MESSAGE_RESTART = 0x3;
        
private 
final WeakReference<TextView> mView;
        
private 
byte mStatus = MARQUEE_STOPPED;
        
private 
final 
float mScrollUnit;
        
private 
float mMaxScroll;
        
private 
float mMaxFadeScroll;
        
private 
float mGhostStart;
        
private 
float mGhostOffset;
        
private 
float mFadeStop;
        
private 
int mRepeatLimit;
        
private 
float mScroll;
        Marquee(TextView v) {
            
final 
float density = v.getContext().getResources()
                    .getDisplayMetrics().density;
            mScrollUnit = (MARQUEE_PIXELS_PER_SECOND * density)
                    / MARQUEE_RESOLUTION;
            mView = 
new WeakReference<TextView>(v);
        }
        @Override
        
public 
void handleMessage(Message msg) {
            
switch (msg.what) {
            
case MESSAGE_START:
                mStatus = MARQUEE_RUNNING;
                tick();
                
break;
            
case MESSAGE_TICK:
                tick();
                
break;
            
case MESSAGE_RESTART:
                
if (mStatus == MARQUEE_RUNNING) {
                    
if (mRepeatLimit >= 0) {
                        mRepeatLimit--;
                    }
                    start(mRepeatLimit);
                }
                
break;
            }
        }
        
void tick() {
            
if (mStatus != MARQUEE_RUNNING) {
                
return;
            }
            removeMessages(MESSAGE_TICK);
            
final TextView textView = mView.get();
            
//
 && (textView.isFocused() || textView.isSelected())
            
if (textView != 
null) {
                mScroll += mScrollUnit;
                
if (mScroll > mMaxScroll) {
                    mScroll = mMaxScroll;
                    sendEmptyMessageDelayed(MESSAGE_RESTART,
                            MARQUEE_RESTART_DELAY);
                } 
else {
                    sendEmptyMessageDelayed(MESSAGE_TICK, MARQUEE_RESOLUTION);
                }
                textView.invalidate();
            }
        }
        
void stop() {
            mStatus = MARQUEE_STOPPED;
            removeMessages(MESSAGE_START);
            removeMessages(MESSAGE_RESTART);
            removeMessages(MESSAGE_TICK);
            resetScroll();
        }
        
private 
void resetScroll() {
            mScroll = 0.0f;
            
final TextView textView = mView.get();
            
if (textView != 
null) {
                textView.invalidate();
            }
        }
        
void start(
int repeatLimit) {
            
if (repeatLimit == 0) {
                stop();
                
return;
            }
            mRepeatLimit = repeatLimit;
            
final TextView textView = mView.get();
            
if (textView != 
null && textView.getLayout() != 
null) {
                mStatus = MARQUEE_STARTING;
                mScroll = 0.0f;
                
final 
int textWidth = textView.getWidth()
                        - textView.getCompoundPaddingLeft()
                        - textView.getCompoundPaddingRight();
                
final 
float lineWidth = textView.getLayout().getLineWidth(0);
                
final 
float gap = textWidth / 3.0f;
                mGhostStart = lineWidth - textWidth + gap;
                mMaxScroll = mGhostStart + textWidth;
                mGhostOffset = lineWidth + gap;
                mFadeStop = lineWidth + textWidth / 6.0f;
                mMaxFadeScroll = mGhostStart + lineWidth + lineWidth;
                textView.invalidate();
                sendEmptyMessageDelayed(MESSAGE_START, MARQUEE_DELAY);
            }
        }
        
float getGhostOffset() {
            
return mGhostOffset;
        }
        
float getScroll() {
            
return mScroll;
        }
        
float getMaxFadeScroll() {
            
return mMaxFadeScroll;
        }
        
boolean shouldDrawLeftFade() {
            
return mScroll <= mFadeStop;
        }
        
boolean shouldDrawGhost() {
            
return mStatus == MARQUEE_RUNNING && mScroll > mGhostStart;
        }
        
boolean isRunning() {
            
return mStatus == MARQUEE_RUNNING;
        }
        
boolean isStopped() {
            
return mStatus == MARQUEE_STOPPED;
        }
    }
}

代码说明: 

1、取消了焦点和选中的判断

2、将延迟1200改为0,立即执行跑马灯效果。

3、核心代码都是直接从TextView拷贝出来。

 

 

结束 

这里主要是提供一种解决问题的思路,实际使用还需要进行相应的修改。

你可能感兴趣的文章
[转]在ASP.NET 2.0中操作数据::创建一个数据访问层
查看>>
Linux命令之chmod详解
查看>>
【java小程序实战】小程序注销功能实现
查看>>
Java中子类能否继承父类的私有属性和方法
查看>>
JVM内存模型详解
查看>>
(六) Git--标签管理
查看>>
建造者模式(Builder)-设计模式(三)
查看>>
Linux-网络运维基础
查看>>
Verilog编程网站学习——门电路、组合电路、时序电路
查看>>
android——学生信息显示和添加
查看>>
Android——ImageSwitcher轮流显示动画
查看>>
Android——利用手机端的文件存储和SQLite实现一个拍照图片管理系统
查看>>
图像调优1:清晰度相关参数MTF,SFR,MTF50,MTF50P 以及TVL的概念以及换算说明
查看>>
罗永浩欲直播带货,京东说可以帮忙联系
查看>>
B站,正在变成下一个“公众号”?
查看>>
小米启动安心服务月 手机家电产品可免费清洁保养
查看>>
刘作虎:一加新品将全系支持 5G
查看>>
滴滴顺风车上线新功能,特殊时期便捷出行
查看>>
不会延期!iPhone 12S预计如期在9月发售:升级三星LTPO屏幕
查看>>
腾讯物联网操作系统TencentOS tiny线上移植大赛,王者机器人、QQ公仔、定制开发板等礼品等你来拿 !
查看>>