Android的TextView支持跑馬燈模式,對於顯示一些單行長字符串還是不錯的,可惜的是TextView要想顯示跑馬燈模式,必須要設置兩個屬性focusableInTouchMode=”true”,focusable=”true”,於是問題來了,如果我要在一個界面同時顯示兩個或兩個以上跑馬燈呢?
老規矩,在節目開始之前,先來一個搞笑段子:
男孩終於鼓足勇氣去向女孩告白:“我喜歡你很久了,你能做我的女朋友嗎?”
女孩說:“對不起,我不能喜歡你,因爲我有男朋友了。”
男孩失落地轉身離去,淚水不住地往下流。
剛走不遠,身後傳來女孩急切的聲音:“你等一下!”
男孩破涕爲笑,滿懷期待地回頭。
女孩說:“就算我沒有男朋友,也不會喜歡你的。”
這兩個屬性不能同時對多個控件生效,所以就不能實現。
於是就有很多小夥伴開始自定義view,自己繪製、做動畫、轉換等,這是正途,對於系統控件不能滿足的需求,我們確實應該優先想到自定義,但是對於這個case,有一個更加簡單的方法。
利用一個小技巧騙過系統的判斷,也可以說是一個小BUG吧。
系統判斷一個TextView有沒有獲得焦點,是通過isFocused()方法,但是如果兩個或兩個以上TextView都設置了上面的兩個屬性,只有一個isFocused()能返回true,這就是爲什麼我們不能實現多個多個TextView同時顯示跑馬燈的原因。
於是,方法來了:我們重寫TextView的isFocused()方法,強制返回true。
public class MarqueeTextView extends TextView {
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
setSingleLine();
setEllipsize(TruncateAt.MARQUEE);
setMarqueeRepeatLimit(-1);
}
public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFocusable(true);
setFocusableInTouchMode(true);
setSingleLine();
setEllipsize(TruncateAt.MARQUEE);
setMarqueeRepeatLimit(-1);
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
if (focused) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
@Override
public void onWindowFocusChanged(boolean focused) {
if (focused) {
super.onWindowFocusChanged(focused);
}
}
@Override
public boolean isFocused() {
return true;
}
}
這樣,系統就會認爲所有的TextView的isFocused()都是true,就可以實現多個跑馬燈的效果。
對於這種方法,我只想說:真是機智啊!!!
好了,本期節目就到這裏,感謝大家的收看,下期再見~