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()方法,没有第一种方式的问题。
推荐第二种方式。