参考网页1:http://www.cnblogs.com/over140/archive/2010/08/20/1804770.html
主要就是给TextView添加如下的一些属性
android:ellipsize="marquee" android:focusable="true" android:marqueeRepeatLimit="marquee_forever" android:focusableInTouchMode="true" android:scrollHorizontally="true"如果不行,就在代码里面调用TextView的requestFocus()函数,使TextView获得焦点。
人的需求无止境,跑马灯效果也需要改进,倘若有多个TextView需要同时执行跑马灯效果呢?这可麻烦了,因为多个TextView只能有一个获取焦点。
但是人还是比较聪明的,知道投梁换柱这一招,来欺骗Android系统,这就是下面这篇博客的做法。
参考网页2:http://blog.csdn.net/aminfo/article/details/7558550
因为每次调用TextView的requestFocus时候,均会导致onFocusChanged被调用。
调用第2个TextView,会首先调用调用第一个TextView的onFocusChanged函数 以此来清除第一个TextView的焦点(参数为false)。
然后再调用第二个TextView的onFocusChanged函数,设定第二个TextView获得焦点。
但是参考网页2有缺点,即不能动态控制多个TextView同时start或者stop这个Marquee效果。
这就是我可以出力的地方。我自定义一个MarqueeTextView类,该类可确保多个TextView同时start or stop Marquee effect。
请看下面代码
package com.reuse.controls; import java.lang.reflect.Field; import android.content.Context; import android.graphics.Rect; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.TextView; /** * 多个TextView中只能有一个获得焦点。 * 使用 setInnerFocus 函数可确保多个TextView同时执行跑马灯效果or not. */ public class MarqueeTextView extends TextView { public MarqueeTextView(Context context) { super(context); Initialize(); } public MarqueeTextView(Context context, AttributeSet attrs) { super(context, attrs); Initialize(); } public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); Initialize(); } private void Initialize() { setFocusable(true); setFocusableInTouchMode(true); setSingleLine(); setEllipsize(TextUtils.TruncateAt.MARQUEE); setMarqueeRepeatLimit(-1); } @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { /** * requestFocus和clearFocus均导致这里被调用 */ if( focused ) { super.onFocusChanged(focused, direction, previouslyFocusedRect); } else { if( !mBMyFocus ) { super.onFocusChanged(focused, direction, previouslyFocusedRect); } } } // @Override // public void onWindowFocusChanged(boolean focused) { // super.onWindowFocusChanged(focused); // } @Override public boolean isFocused() { return mBMyFocus; } //////////////////////////////////////////////////// private boolean mBMyFocus = false; public void setInnerFocus( boolean bFocus ) { mBMyFocus = bFocus; if( mBMyFocus ) { requestFocus(); } else { Field field; try { field = getClass().getSuperclass().getSuperclass().getDeclaredField("mPrivateFlags"); field.setAccessible(true); field.set(this, new Integer(2)); clearFocus(); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////