国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android應(yīng)用中clearFocus方法調(diào)用無效的問題解決

2019-12-12 06:23:51
字體:
供稿:網(wǎng)友

clearFocus 無效?

EditText在focus與非focus的時候,顯示效果是不同的:focus的時候光標是閃的,而且我們通常也會給它設(shè)置selector,focus的時候給它加上邊框之類的.

通常當我們觸摸EditText之外的View時,需要清除EditText的焦點.很自然的就會想到EditText.clearFocus(),然而常常并沒有用.(EditText.isFocus()依然是true,光標也依然在跳躍...)

clearFocus的實現(xiàn)

clearFocus的調(diào)用棧(重要的部分):

View.clearFocus() ->  View.clearFocusInternal() ->  {    1. mParent.clearChildFocus(this);// 從該View一直向上遍歷父節(jié)點,知道DecorView,作用是將parent(ViewGroup)中存儲的mFocus設(shè)置為null,即清除焦點    2. rootViewRequestFocus();// 調(diào)用DecorView的requestFocus()方法,作用是找到視圖中的一個View,并將其設(shè)置為焦點  }

根據(jù)上面列出的調(diào)用棧可以看出,清除focus其實包含2個部分的操作:

清除當前當前View的focus標志,并且清除它的祖先節(jié)點中存儲的mFocus信息
調(diào)用DecorView的requestFocus()方法,重新尋找一個View,并將其設(shè)置為focus
requestFocus()的實現(xiàn)

requestFocus(int)支持FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT 4個參數(shù)來表示focus的流向,然而事實上傳入的方向參數(shù)并沒有作用.(這個其實比較好理解,以FOCUS_RIGHT來說,是該選擇右子樹種的View,還是繪制在右邊的View呢?)

不管傳怎樣的參數(shù),requestFocus()都是以先序遍歷的方式,找到第一個focusInTouchMode的View,并將其設(shè)置為焦點.
設(shè)置的方式是:

給當前View focus標志(mPrivateFlags)
調(diào)用mParent.requestChildFocus()將自己賦值給其父View的mFocus,然后父View再調(diào)用mParent.requestChildFocus()一直到DecorView.
這樣從DecorView開始,只要根據(jù)mFocus就可以找到真正focus的View

@Overridepublic 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這種尋找策略,那么給定一個起始點,那么尋找到的View將始終相同,也就是說,你多次調(diào)用DecorView.requestFocus(),獲得的焦點都是相同的,如果沒有改變視圖層級以及focusable的話.因此當你想讓某個特定的View獲得焦點的話,就應(yīng)該直接調(diào)用它的requestFocus()方法.

tips:對于ViewGroup來說,可以通過descendantFocusability的設(shè)置來選擇優(yōu)先讓parent,還是child獲得焦點.可選值:FOCUS_BEFORE_DESCENDANTS(默認), FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS.

clearFocus 真的無效嗎?

當然不是,之所以有時候發(fā)現(xiàn)EditText.clearFocus()無效,是因為:清除focus之后,還會按照先序遍歷的順序查找一個focusInTouchMode的View,并將其設(shè)置為focus,而你的EditText恰好是這第一個符合條件的View.(因此不是沒清除成功,而是清除了之后,又給設(shè)置上了!!)

知道了原因之后,解決就很簡單了,找一個在EditText之前的View,將其設(shè)置為可獲得焦點的

View.setFocusableInTouchMode(true)android:focusableInTouchMode="true"

如果不知道怎樣找到一個在EditText之前的View的話,那你可以直接選擇它的parent (xxxLayout),因為ViewGroup默認的策略是: FOCUS_BEFORE_DESCENDANTS

判斷是否focus

isFocused(), 它判斷自己是否擁有焦點
hasFocus(), 它判斷自己或著自己的child是否擁有焦點 常用

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 化隆| 阳春市| 阳山县| 石门县| 嘉定区| 新民市| 米泉市| 鹤岗市| 贡嘎县| 呼图壁县| 土默特右旗| 普格县| 陇南市| 佛坪县| 措美县| 莱州市| 商南县| 鄱阳县| 谢通门县| 抚顺市| 佛冈县| 亚东县| 梅河口市| 义乌市| 孝昌县| 都匀市| 白银市| 稷山县| 嘉定区| 大埔区| 平安县| 永仁县| 遂溪县| 南丰县| 铜山县| 德保县| 茂名市| 永修县| 青神县| 贞丰县| 民勤县|