Android應(yīng)用中clearFocus方法調(diào)用無(wú)效的問(wèn)題解決
clearFocus 無(wú)效?
EditText在focus與非focus的時(shí)候,顯示效果是不同的:focus的時(shí)候光標(biāo)是閃的,而且我們通常也會(huì)給它設(shè)置selector,focus的時(shí)候給它加上邊框之類(lèi)的.
通常當(dāng)我們觸摸EditText之外的View時(shí),需要清除EditText的焦點(diǎn).很自然的就會(huì)想到EditText.clearFocus(),然而常常并沒(méi)有用.(EditText.isFocus()依然是true,光標(biāo)也依然在跳躍...)
clearFocus的實(shí)現(xiàn)
clearFocus的調(diào)用棧(重要的部分):
View.clearFocus() ->
View.clearFocusInternal() ->
{
1. mParent.clearChildFocus(this);// 從該View一直向上遍歷父節(jié)點(diǎn),知道DecorView,作用是將parent(ViewGroup)中存儲(chǔ)的mFocus設(shè)置為null,即清除焦點(diǎn)
2. rootViewRequestFocus();// 調(diào)用DecorView的requestFocus()方法,作用是找到視圖中的一個(gè)View,并將其設(shè)置為焦點(diǎn)
}
根據(jù)上面列出的調(diào)用??梢钥闯?清除focus其實(shí)包含2個(gè)部分的操作:
清除當(dāng)前當(dāng)前View的focus標(biāo)志,并且清除它的祖先節(jié)點(diǎn)中存儲(chǔ)的mFocus信息
調(diào)用DecorView的requestFocus()方法,重新尋找一個(gè)View,并將其設(shè)置為focus
requestFocus()的實(shí)現(xiàn)
requestFocus(int)支持FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT 4個(gè)參數(shù)來(lái)表示focus的流向,然而事實(shí)上傳入的方向參數(shù)并沒(méi)有作用.(這個(gè)其實(shí)比較好理解,以FOCUS_RIGHT來(lái)說(shuō),是該選擇右子樹(shù)種的View,還是繪制在右邊的View呢?)
不管傳怎樣的參數(shù),requestFocus()都是以先序遍歷的方式,找到第一個(gè)focusInTouchMode的View,并將其設(shè)置為焦點(diǎn).
設(shè)置的方式是:
給當(dāng)前View focus標(biāo)志(mPrivateFlags)
調(diào)用mParent.requestChildFocus()將自己賦值給其父View的mFocus,然后父View再調(diào)用mParent.requestChildFocus()一直到DecorView.
這樣從DecorView開(kāi)始,只要根據(jù)mFocus就可以找到真正focus的View
@Override
public View findFocus() {
if (DBG) {
System.out.println("Find focus in " + this + ": flags="
+ isFocused() + ", child=" + mFocused);
}
if (isFocused()) {
return this;
}
if (mFocused != null) {
return mFocused.findFocus();
}
return null;
}
注意:按照requestFocus這種尋找策略,那么給定一個(gè)起始點(diǎn),那么尋找到的View將始終相同,也就是說(shuō),你多次調(diào)用DecorView.requestFocus(),獲得的焦點(diǎn)都是相同的,如果沒(méi)有改變視圖層級(jí)以及focusable的話.因此當(dāng)你想讓某個(gè)特定的View獲得焦點(diǎn)的話,就應(yīng)該直接調(diào)用它的requestFocus()方法.
tips:對(duì)于ViewGroup來(lái)說(shuō),可以通過(guò)descendantFocusability的設(shè)置來(lái)選擇優(yōu)先讓parent,還是child獲得焦點(diǎn).可選值:FOCUS_BEFORE_DESCENDANTS(默認(rèn)), FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS.
clearFocus 真的無(wú)效嗎?
當(dāng)然不是,之所以有時(shí)候發(fā)現(xiàn)EditText.clearFocus()無(wú)效,是因?yàn)?清除focus之后,還會(huì)按照先序遍歷的順序查找一個(gè)focusInTouchMode的View,并將其設(shè)置為focus,而你的EditText恰好是這第一個(gè)符合條件的View.(因此不是沒(méi)清除成功,而是清除了之后,又給設(shè)置上了!!)
知道了原因之后,解決就很簡(jiǎn)單了,找一個(gè)在EditText之前的View,將其設(shè)置為可獲得焦點(diǎn)的
View.setFocusableInTouchMode(true) android:focusableInTouchMode="true"
如果不知道怎樣找到一個(gè)在EditText之前的View的話,那你可以直接選擇它的parent (xxxLayout),因?yàn)閂iewGroup默認(rèn)的策略是: FOCUS_BEFORE_DESCENDANTS
判斷是否focus
isFocused(), 它判斷自己是否擁有焦點(diǎn)
hasFocus(), 它判斷自己或著自己的child是否擁有焦點(diǎn) 常用
相關(guān)文章
Android開(kāi)發(fā)獲取當(dāng)前系統(tǒng)日期和時(shí)間功能示例
這篇文章主要介紹了Android開(kāi)發(fā)獲取當(dāng)前系統(tǒng)日期和時(shí)間功能,結(jié)合實(shí)例形式分析了Android布局、事件響應(yīng)、監(jiān)聽(tīng)以及時(shí)間獲取相關(guān)操作技巧,需要的朋友可以參考下2019-04-04
一文詳解Android無(wú)需權(quán)限調(diào)用系統(tǒng)相機(jī)拍照
這篇文章主要為大家介紹了Android無(wú)需權(quán)限調(diào)用系統(tǒng)相機(jī)拍照詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Android開(kāi)發(fā)中requestfocus()無(wú)效的原因及解決辦法
這篇文章主要介紹了Android開(kāi)發(fā)中requestfocus()無(wú)效的原因及解決辦法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08
Android實(shí)現(xiàn)局部圖片滑動(dòng)指引效果示例
現(xiàn)在滑動(dòng)效果用的比較多,尤其是在手機(jī)端上面,本文介紹了Android實(shí)現(xiàn)局部圖片滑動(dòng)指引效果示例,現(xiàn)在就分享給大家,也給大家做個(gè)參考。2016-10-10
android中soap協(xié)議使用(ksoap調(diào)用webservice)
kSOAP是如何調(diào)用ebservice的呢,首先要使用SoapObject,這是一個(gè)高度抽象化的類(lèi),完成SOAP調(diào)用??梢哉{(diào)用它的addProperty方法填寫(xiě)要調(diào)用的webservice方法的參數(shù)2014-02-02
Android編程使用AlarmManager設(shè)置鬧鐘的方法
這篇文章主要介紹了Android編程使用AlarmManager設(shè)置鬧鐘的方法,結(jié)合具體實(shí)例分析了Android基于AlarmManager實(shí)現(xiàn)鬧鐘功能的設(shè)置、取消、顯示等相關(guān)操作技巧,需要的朋友可以參考下2017-03-03
Android編程實(shí)現(xiàn)帶有單選按鈕和復(fù)選按鈕的dialog功能示例
這篇文章主要介紹了Android編程實(shí)現(xiàn)帶有單選按鈕和復(fù)選按鈕的dialog功能,結(jié)合具體實(shí)例形式分析了Android實(shí)現(xiàn)帶有單選按鈕的dialog對(duì)話框及帶有復(fù)選按鈕的dialog對(duì)話框相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
Android刮刮卡實(shí)現(xiàn)原理與代碼講解
這篇文章主要為大家詳細(xì)介紹了Android刮刮卡實(shí)現(xiàn)原理、實(shí)現(xiàn)原理步驟以及代碼講解,感興趣的小伙伴們可以參考一下2016-04-04

