TextView的跑马灯效果实现

问题描述

当文字内容过长,但是只允许显示一行时,可以将文字显示为跑马灯效果,即文字滚动显示。

代码实现

第一种方法实现

先查询TextView控件的属性,得到以下信息:

  • android:ellipsize=”marquee”
    TextView采用跑马灯属性.
  • android:marqueeRepeatLimit=”marquee_forever”
    设置重复滚动的次数,marquee_forever表示无限次.

在设置了上面两个属性之后,还需要设置两个属性,使得TextView可以获得焦点,滚动起来,不获取焦点,TextView并不会滚动。

  • android:focusableInTouchMode=”true”
    在Touch模式下可以获取焦点。
  • android:focusable=”true”
    TextView可以获取焦点。

TextView的设置属性如下:

<TextView
        android:id="@+id/tv"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:ellipsize="marquee"
        android:focusableInTouchMode="true"
        android:focusable="true"
        android:gravity="center"
        android:marqueeRepeatLimit="marquee_forever"
        android:singleLine="true"
        android:text="Hello World!相当长的内容,只能显示一行,内容太多,显示不下,所以采用跑马灯方式显示,哈哈哈哈哈。。。" 
/>

这种方法实现存在一个问题,就是当其他控件获取焦点之后,TextView没有了焦点,则会停止跑马灯效果。
在TextView控件下面添加一个EditText控件,当点击EditText控件时,EditText控件将会获得焦点,TextView将会失去焦点,代码如下:

    <TextView
        android:id="@+id/tv"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:ellipsize="marquee"
        android:focusableInTouchMode="true"
        android:focusable="true"
        android:gravity="center"
        android:marqueeRepeatLimit="marquee_forever"
        android:singleLine="true"
        android:text="Hello World!相当长的内容,只能显示一行,内容太多,显示不下,所以采用跑马灯方式显示,哈哈哈哈哈。。。" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_below="@id/tv"
        />

运行代码之后,点击EditText,上面的TextView就会停止跑马灯效果,所以如果布局上有其他控件就不适合第一种方式。

第二种方法实现

通过修改TextView的isFocus()方法,使其返回为true,可以一直获取焦点。代码如下:

public class FocusTextView extends TextView{

    public FocusTextView(Context context) {
        super(context);
    }

    public FocusTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public FocusTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

FocusTextView的使用为:

<com.zhangmiao.sixproject.FocusTextView
        android:id="@+id/focus_tv"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:ellipsize="marquee"
        android:gravity="center"
        android:marqueeRepeatLimit="marquee_forever"
        android:singleLine="true"
        android:layout_below="@id/tv"
        android:text="Hello World!相当长的内容,只能显示一行,内容太多,显示不下,所以采用跑马灯方式显示,哈哈哈哈哈。。。" 
/>

这种方式就不会有第一种方式的问题。

总结

第一种方式实现方便快捷,但是存在被其他控件夺取焦点之后效果消失的问题。
第二种方式需要实现一个类去继承TextView,重写isFocus()方法,没有第一种方式的问题。
推荐第二种方式。

联系方式:1006299425@qq.com,有问题欢迎大家指出。

版权声明:本文为zhangmiao14原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zhangmiao14/p/8759282.html