Android移動應(yīng)用中的焦點分析

什么是焦點

簡單一點理解,在移動應(yīng)用中侄旬,焦點就是當(dāng)前正在處理事件的位置望抽。在手機(jī)應(yīng)用中加矛,最有可能用到焦點的就是EditText,如果同一個界面中有多個EditText煤篙,通常情況下同一時間只有一個能夠輸入內(nèi)容斟览,此時,這個EditText就獲取了焦點辑奈。

在Android中苛茂,對焦點的設(shè)置分為兩種情況,TouchMode和非TouchMode○埃現(xiàn)在的手機(jī)基本都是觸摸屏妓羊,我們用手指觸摸屏幕來操作Android應(yīng)用時,處于TouchMode稍计。除了TouchMode之外躁绸,還有非TouchMode,利用外接設(shè)備來操作應(yīng)用臣嚣。比如鍵盤净刮。使用Genymotion模擬器的時候,一個界面上有多個控件時茧球,可以用電腦tab鍵來進(jìn)行移動庭瑰,被選中的控件會高亮顯示,這時候就是非TouchMode抢埋,被選中的控件獲得了焦點弹灭。

焦點的使用

在手機(jī)應(yīng)用中,用到焦點的時候并不多揪垄,但是TV應(yīng)用中穷吮,需要用遙控器來操作選中控件,這時候就需要對焦點進(jìn)行處理了饥努。關(guān)于焦點捡鱼,常用方法如下:

isFocusableInTouchMode() //在TouchMode中是否能夠獲取焦點
isFocusable()//是否能獲取焦點
setFocusableInTouchMode(boolean) //設(shè)置在TouchMode中是否能夠獲取焦點
setFocusable(boolean) //設(shè)置是否能獲取焦點
setOnFocusChangeListener()//設(shè)置焦點變化監(jiān)聽
OnFocusChangeListener()
requestFocus() //獲取焦點
isFocused()//是否獲取到焦點

在View類中,isFocusable()isFocusableInTouchMode()獲取到的結(jié)果都是false酷愧,也就是說驾诈,直接繼承自View的控件是不能獲取焦點的缠诅。我們常用控件中對這兩個方法進(jìn)行了改寫,比如EditText乍迄,這兩個方法都是true管引,而Button則只有isFocusable()返回true。這也就是為什么我們用tab鍵選取Button的時候能夠高亮顯示闯两,而鼠標(biāo)點擊(模擬觸控)的時候不能高亮顯示的原因了褥伴。如果想在點擊的時候也能高亮顯示Button,需要手動設(shè)置setFocusableInTouchMode(true)漾狼,就可以了重慢。

如果想對控件的焦點狀態(tài)進(jìn)行監(jiān)聽,需要設(shè)置setOnFocusChangeListener()逊躁,只要控件的焦點狀態(tài)發(fā)生變化(獲得或者失去焦點)似踱,都會調(diào)用onFocusChange方法

關(guān)于焦點的移動,默認(rèn)的算法會尋找指定方向上最近的可以獲取焦點的元素(非TouchMode)志衣。另外在創(chuàng)建控件的時候屯援,也可以指定尋找焦點的方向,設(shè)置nextFocusDown念脯、nextFocusLeft狞洋、nextFocusRight 和 nextFocusUp的值為指定元素就可以了÷痰辏看以下例子:

<LinearLayout
    android:orientation="vertical"
    ... >
  <Button android:id="@+id/top"
          android:nextFocusUp="@+id/bottom"
          ... />
  <Button android:id="@+id/bottom"
          android:nextFocusDown="@+id/top"
          ... />
</LinearLayout>

這里指定了上面的button向上尋找焦點時吉懊,下一個元素是id為bottom的元素,也就是說假勿,上面的Button在獲取了焦點之后借嗽,繼續(xù)按向上鍵,系統(tǒng)會將焦點移動到id為bottom的元素上转培,而不是繼續(xù)向上恶导。

焦點與事件

在開發(fā)手機(jī)應(yīng)用的過程中,對焦點的處理并不多浸须,它與事件是兩個不同的體系惨寿,通常情況下焦點和事件是相互獨(dú)立并不沖突。但是在Button的點擊事件中會有一點問題删窒。如果我們隊一個button設(shè)置了setFocusableInTouchMode(true)裂垦,使他可以獲取焦點,那么我們點擊這個button的時候肌索,第一次點擊并不會執(zhí)行onClick()方法蕉拢,而是執(zhí)行onFocusChange()。第二次點擊的時候才會執(zhí)行onClick()方法≡位唬看起來好像onFocusChange()消耗了點擊事件午乓,實際上并不是的。

這個問題我們看一下源碼就清楚了:

onClick()方法是在onTouchEvent的ACTION_UP里調(diào)用的届巩,看一下View的onTouchEvent方法:

           switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                   ......
                        boolean focusTaken = false;
                        if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
                            focusTaken = requestFocus();
                        }
                          ......
                            // Only perform take click actions if we were in the pressed state
                            if (!focusTaken) {
                                // Use a Runnable and post this rather than calling
                                // performClick directly. This lets other visual state
                                // of the view update before click actions start.
                                if (mPerformClick == null) { 
                                    mPerformClick = new PerformClick();
                                }
                                if (!post(mPerformClick)) {
                                    performClick();
                                }
                            }
                        }

可以看到硅瞧,只有當(dāng)focusTaken為false的時候才會執(zhí)行onClick,focusTaken的值默認(rèn)是false的恕汇,但是在isFocusable() && isFocusableInTouchMode() && !isFocused()為true的時候,會去requestFocus獲取焦點或辖,并將值賦給focusTaken瘾英。

關(guān)鍵在于isFocused(),如果當(dāng)前Button沒有獲取焦點颂暇,isFocused()返回false缺谴,!isFocused()值為ture,Button就會去獲取焦點耳鸯,從而導(dǎo)致focusTaken為true湿蛔,onClick方法就不會執(zhí)行了,只有Button已經(jīng)獲取了焦點的時候才會執(zhí)行onClick方法县爬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阳啥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子财喳,更是在濱河造成了極大的恐慌察迟,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耳高,死亡現(xiàn)場離奇詭異扎瓶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)泌枪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門概荷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碌燕,你說我怎么就攤上這事误证。” “怎么了陆蟆?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵雷厂,是天一觀的道長。 經(jīng)常有香客問我叠殷,道長改鲫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮像棘,結(jié)果婚禮上稽亏,老公的妹妹穿的比我還像新娘。我一直安慰自己缕题,他們只是感情好截歉,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烟零,像睡著了一般瘪松。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锨阿,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天宵睦,我揣著相機(jī)與錄音,去河邊找鬼墅诡。 笑死壳嚎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的末早。 我是一名探鬼主播烟馅,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼然磷!你這毒婦竟也來了郑趁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤样屠,失蹤者是張志新(化名)和其女友劉穎穿撮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痪欲,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悦穿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了业踢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栗柒。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖知举,靈堂內(nèi)的尸體忽然破棺而出瞬沦,到底是詐尸還是另有隱情,我是刑警寧澤雇锡,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布逛钻,位于F島的核電站,受9級特大地震影響锰提,放射性物質(zhì)發(fā)生泄漏曙痘。R本人自食惡果不足惜芳悲,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望边坤。 院中可真熱鬧名扛,春花似錦、人聲如沸茧痒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旺订。三九已至弄企,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耸峭,已是汗流浹背桩蓉。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留劳闹,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓洽瞬,卻偏偏與公主長得像本涕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子伙窃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容