TextView是安卓中最常用的文本显示控件之一,但是作为文本显示控件,它所能显示的字数是有限的,那么问题来了,我们如何利用TextView来滚动显示一个长文本内容呢?

    先来看看我们想要实现的效果

android 进入后TextView获取焦点 安卓获取textview内容_android

可以看到一个长文本在TextView中循环的从右向左移动,通过这种方式我们就能在TextView中显示长发文本了,下面我们来看看如何实现这个功能

    首先我们先写一个MyTextView类,让他继承TextView,并重写isFocused方法,修改其返回值为true。这样修改后,用过MyTextView实现的TextView控件将会默认获得焦点。
    代码
package com.example.lowp.textviewoverlength_test;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created by Lowp on 2015/9/7.
 */
public class MyTextView extends TextView {


    /**
     * 实现构造方法
     * @param context
     * @param attrs
     */
    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }



    /**
     * 让所有的实现该TextView都默认获得焦点
     * @return
     */
    @Override
    public boolean isFocused() {
        return true;
    }
}
然后,我们在布局文件中通过上面的类来实现TextView控件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <com.example.lowp.textviewoverlength_test.MyTextView
        android:padding="20dp"
        android:singleLine="true"
        android:text="@string/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ellipsize="marquee">

    <com.example.lowp.textviewoverlength_test.MyTextView
        android:padding="20dp"
        android:singleLine="true"
        android:text="@string/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ellipsize="marquee"/>

</LinearLayout>
<resources>
    。。。
    <string name="test"> 使用DOM4J的方式解析XML同样需要第三方jar包,如果你对前面三种解析方法都有所了解,那么用过DOM4J方式来解析xml就不会陌生了,话不多说直接上代码</string>
    。。。
</resources>
其中要注意的一个属性:
    android:ellipsize="marquee"     跑马灯显示文本内容 

    通过以上方式,我们就是实现了TextView实现“跑马灯”式显示长文本,看到这里可能很多朋友会有疑问:既然通过设置android:ellipsize可以实现“跑马灯”效果,为什么还要去写MyTextView这个类呢?

    我们在布局文件中添加一下代码
<TextView
        android:padding="20dp"
        android:singleLine="true"
        android:text="@string/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:focusable="true"
        android:focusableInTouchMode="true"
        android:ellipsize="marquee" />
其中的一些属性:
    android:focusable="true"     允许获得焦点
    android:focusableInTouchMode="true"    触屏模式下获得焦点

    这里顺便补充一下,TextView只有在获得焦点的情况下才能实现“跑马灯”效果。所以android:focusable="true",android:focusableInTouchMode="true",android:ellipsize="marquee" 这三个属性缺一不可!!!

    实现效果如下:

android 进入后TextView获取焦点 安卓获取textview内容_textview_02

可以看到,同样实现了“跑马灯”效果。但是如果我们用同样的方式再添加一个TextView,还会实现一个“跑马灯”效果吗?

    我们再在布局文件中添加一下代码
<TextView
        android:padding="20dp"
        android:singleLine="true"
        android:text="@string/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:focusable="true"
        android:focusableInTouchMode="true"
        android:ellipsize="marquee" />
这次的效果:

android 进入后TextView获取焦点 安卓获取textview内容_textview_03

可以看到,第四行的TextView并没有滑动,当某一控件获得焦点时,会将其他控件的焦点抢去,这就导致了同一时间只能有一个控件获取焦点。所以我们通过MyTextView这个类重写了父类的isFocused方法,让通过MyTextView实现的TextView控件强制获取焦点,这样就能在有多个TextView的情况下同时实现“跑马灯”效果了!!!