Android 里 TextView 控件本身就带有跑马灯的效果,但会存在 EditText 和 Dialog 抢占焦距使跑马灯效果失效等问题。
用 TextView 实现跑马灯效果,只需关注5个属性:
页面上出现两个跑马灯效果时
效果图:
问题:会发现一个问题,只有第一个 TextView 会有走马灯的效果
原因:第一个 TextView 抢占了焦距
解决方法:自定义 TextView 来实现跑马灯
public class MarqueeTextView extends android.support.v7.widget.AppCompatTextView {
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MarqueeTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 设置单行
setSingleLine();
// setMaxLines(1);
//设置 Ellipsize,setMaxLines(1) 和 setEllipsize 冲突
setEllipsize(TextUtils.TruncateAt.MARQUEE);
//获取焦距
setFocusable(true);
//走马灯的重复次数,-1代表无限重复
setMarqueeRepeatLimit(-1);
//强制获得焦点
setFocusableInTouchMode(true);
}
/**
* 使这个 View 永远获得焦距
* @return true
*/
@Override
public boolean isFocused() {
return true;
}
}
布局文件
此时如果在布局上加一个 EditText 控件,会是什么效果呢?
问题:加了 EditText 控件后,当 EditText 获得焦距后,第一个跑马灯停止了
原因:因为 EditText 抢占了焦距
解决方法:在自定义 TextView 中,重写父类的 onFocusChanged 方法
/**
* 用于 EditText 存在时抢占焦点
*/
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if(focused){
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
隐形问题:
当弹出软键盘时(即 EditText 获得焦距时),跑马灯会重头开始播放;当关闭软键盘时(即 EditText 失去焦距时),跑马灯也会重头开始播放
尚未解决,哪位大神指点下???
如果桌面上弹出一个对话框,会是什么效果?
问题:当弹出对话框时,跑马灯效果停止了
原因:Dialog 抢占了焦距
解决方法:在自定义 TextView 中,重写父类的 onWindowFocusChanged 方法
/**
* Window与Window间焦点发生改变时的回调
* 解决 Dialog 抢占焦点问题
* @param hasWindowFocus
*/
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if(hasWindowFocus){
super.onWindowFocusChanged(hasWindowFocus);
}
}
自定义跑马灯完整代码
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
/**
* Created by sgll on 2018/11/20.
* 自定义:跑马灯
* 解决:
* 1、EditText 存在时抢占焦距,使跑马灯停止的问题:重写父类的 onFocusChanged 方法
* 2、弹出对话框后,跑马灯停止的问题:重写父类的 onWindowFocusChanged 方法
*/
public class MarqueeTextView extends android.support.v7.widget.AppCompatTextView {
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
// 设置单行
setSingleLine();
// setMaxLines(1);
//设置 Ellipsize,setMaxLines(1) 和 setEllipsize 冲突
setEllipsize(TextUtils.TruncateAt.MARQUEE);
//获取焦距
setFocusable(true);
//走马灯的重复次数,-1代表无限重复
setMarqueeRepeatLimit(-1);
//强制获得焦点
setFocusableInTouchMode(true);
}
/**
* 使这个 View 永远获得焦距
* @return true
*/
@Override
public boolean isFocused() {
return true;
}
/**
* 用于 EditText 存在时抢占焦点
*/
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if(focused){
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
/**
* Window与Window间焦点发生改变时的回调
* 解决 Dialog 抢占焦点问题
* @param hasWindowFocus
*/
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if(hasWindowFocus){
super.onWindowFocusChanged(hasWindowFocus);
}
}
}