最近大学同学在写一个跑马灯效果时候遇到一些坑,聊天刚好说到这个东西,说搞了半天还是有问题,恰好之前的项目自己也做了这个效果,然后就顺手帮他写了个简单的跑马灯效果换一顿饭
需求
一个在首页需要一直循环的跑马灯效果,首页有可能有其他比如editText等影响
思路
1.布局文件直接实现
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Hello WorldXXXXXXXXXXXXXXXXXXXXXXXXXX!"
android:maxLines="1"
android:marqueeRepeatLimit="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
ellipsize="narquee"
app:layout_constraintTop_toTopOf="parent"/>
这样是最基本的效果,但是这样肯定是在某些情况失去焦点了就停了。
改成自定义:
/**
* 文件描述: 跑马灯效果
* Created by xn069392
* 创建时间 2018/5/29
*/
public class LoopScrollText extends android.support.v7.widget.AppCompatTextView {
public LoopScrollText(Context context) {
this(context,null);
}
public LoopScrollText(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
setSingleLine();
setMarqueeRepeatLimit(-1);
setEllipsize(TextUtils.TruncateAt.MARQUEE);
setFocusable(true);
setFocusableInTouchMode(true);
}
}
很简单的就实现了,但是这个还是有问题的
当界面有EditText控件抢夺焦点时候会停止
重写两个方法 ,第一个方法,是否有焦点,让他返回true 就是让他一直有焦点,这样做是不行的,这个是自己宣布在自己的控件一直持有焦点,但是真正有没 还有处理当有焦点的时候,吧焦点事件交给父容器处理
@Override
public boolean isFocused() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (focused)
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
效果如下:
edit.gif
当界面弹dialog失去焦点
当给界面加了点击事件,弹出一个dialog,这个时候 焦点会被抢走,效果如下:
dialog.gif
这个处理界面的操作 就是onWindowFocusChanged 这个回调方法,就是窗口焦点改变时候的回调
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (hasWindowFocus)
super.onWindowFocusChanged(hasWindowFocus);
}
当我的自定义滚动的控件有焦点时候,我让父容器去管理,当我没有焦点时候,不做任何处理效果如下:
gg.gif
分析
1.isFocused
2.onFocusChanged
3.onWindowFocusChanged
上面方法在EditText 和Dialog 出现抢焦点 当我拿到这个焦点时候,我走父类的方法,当我没拿到 我不走 父类的方法(这个 事件传递 是 View 实现的,我不让View 搞我的事件 走之前的状态)
github地址:https://github.com/zh2016hz/LoopScrollText.git