[Android] TextView跑马灯效果

写法

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:singleLine="true"
        android:text="我是跑马灯,但是有的时候会有些坑,比如不滚动。我是跑马灯,但是有的时候会有些坑,比如不滚动。" />

关于不滚动

  • setSelect(true)
    自己写Demo的时候发现,在一个布局里有两个TextView需要同时跑马灯时,第一个TextView正常滚动,第二个一直没有效果,于是尝试调用TextView的setSelect(true)方法触发滚动,结果两个都正常滚动。

    从TextView代码中,触发开始滚动方法的部分代码,可以看到在TextView的select状态从false变为true,并且ellipsize为MARQUEE时,会触发startMarquee()方法,开始滚动。

    @Override
    public void setSelected(boolean selected) {
        boolean wasSelected = isSelected();
    
        super.setSelected(selected);
    
        if (selected != wasSelected && mEllipsize == TextUtils.TruncateAt.MARQUEE) {
            if (selected) {
                startMarquee();
            } else {
                stopMarquee();
            }
        }
    }
    
  • requestFocus()
    在项目中,使用setSelect(true)却不生效。然而并不知道是布局里面其他自定义View的问题还是DataBinding的问题。无意中关闭锁屏再打开发现TextView竟然开始滚动了!于是猜测是TextView没能及时获取焦点导致。后来尝试调用requestFocus(),问题解决。

关于RecyclerView和跑马灯焦点的冲突

当跑马灯TextView存在于RecyclerView的Item中时,如果默认在初始化的时候执行requestFocus()操作会导致:

  • RecyclerView焦点乱飞,初始位置不一定是列表的首个Item;
  • RecyclerView滑动到跑马灯Item不显示位置后,重新滑回显示位置,跑马灯TextView失去焦点,于是不会再滚动。

解决方案

  • 不在初始化的时候执行requestFocus()操作;
  • 监听RecyclerView的Scroll事件,判断当前跑马灯Item是否显示在当前窗口,显示则获取焦点,不显示就不执行获取焦点操作。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容