EditText點選外部退出編輯
思路:重寫EdieText父佈局的dispatchTouchEvent()方法,判斷EditText正在獲取焦點並且點選外部時呼叫EditText的clearFocus()方法,並關閉軟鍵盤。
public class EditTextLinearLayout extends LinearLayout {
public EditTextLinearLayout(Context context,AttributeSet attrs) {
super(context,attrs);
setFocusableInTouchMode(true);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = ((Activity)getContext()).getCurrentFocus();
if(isShouldHideInput(v,ev)) {
InputMethodManager imm = (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if(imm !=null) {
imm.hideSoftInputFromWindow(v.getWindowToken(),0);
}
}
}
return super.dispatchTouchEvent(ev);
}
private boolean isShouldHideInput(View v,MotionEvent event) {
if(v !=null&& (vinstanceofEditText)) {
int[] leftTop = {0,0};
//獲取輸入框當前的location位置
v.getLocationInWindow(leftTop);
intleft = leftTop[0];
inttop = leftTop[1];
intbottom = top + v.getHeight();
intright = left + v.getWidth();
if(event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 點選的是輸入框區域,保留點選EditText的事件
return false;
}else{
v.clearFocus();
return true;
}
}
return false;
}
Android應用中clearFocus方法呼叫無效的問題解決
clearFocus 無效?
EditText在focus與非focus的時候,顯示效果是不同的:focus的時候游標是閃的,而且我們通常也會給它設定selector,focus的時候給它加上邊框之類的.
通常當我們觸控EditText之外的View時,需要清除EditText的焦點.很自然的就會想到EditText.clearFocus(),然而常常並沒有用.(EditText.isFocus()依然是true,游標也依然在跳躍...)
clearFocus的實現
clearFocus的呼叫棧(重要的部分):
View.clearFocus() ->
View.clearFocusInternal() ->
{
mParent.clearChildFocus(this);// 從該View一直向上遍歷父節點,知道DecorView,作用是將parent(ViewGroup)中儲存的mFocus設定為null,即清除焦點
rootViewRequestFocus();// 呼叫DecorView的requestFocus()方法,作用是找到檢視中的一個View,並將其設定為焦點
}
根據上面列出的呼叫棧可以看出,清除focus其實包含2個部分的操作:
清除當前當前View的focus標誌,並且清除它的祖先節點中儲存的mFocus資訊
呼叫DecorView的requestFocus()方法,重新尋找一個View,並將其設定為focus
requestFocus()的實現
requestFocus(int)支援FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT 4個引數來表示focus的流向,然而事實上傳入的方向引數並沒有作用.(這個其實比較好理解,以FOCUS_RIGHT來說,是該選擇右子樹種的View,還是繪製在右邊的View呢?)
不管傳怎樣的引數,requestFocus()都是以先序遍歷的方式,找到第一個focusInTouchMode的View,並將其設定為焦點.
設定的方式是:
給當前View focus標誌(mPrivateFlags)
呼叫mParent.requestChildFocus()將自己賦值給其父View的mFocus,然後父View再呼叫mParent.requestChildFocus()一直到DecorView.
這樣從DecorView開始,只要根據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這種尋找策略,那麼給定一個起始點,那麼尋找到的View將始終相同,也就是說,你多次呼叫DecorView.requestFocus(),獲得的焦點都是相同的,如果沒有改變檢視層級以及focusable的話.因此當你想讓某個特定的View獲得焦點的話,就應該直接呼叫它的requestFocus()方法.
tips:對於ViewGroup來說,可以通過descendantFocusability的設定來選擇優先讓parent,還是child獲得焦點.可選值:FOCUS_BEFORE_DESCENDANTS(預設), FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS.
clearFocus 真的無效嗎?
當然不是,之所以有時候發現EditText.clearFocus()無效,是因為:清除focus之後,還會按照先序遍歷的順序查詢一個focusInTouchMode的View,並將其設定為focus,而你的EditText恰好是這第一個符合條件的View.(因此不是沒清除成功,而是清除了之後,又給設定上了!!)
知道了原因之後,解決就很簡單了,找一個在EditText之前的View,將其設定為可獲得焦點的
View.setFocusableInTouchMode(true)
android:focusableInTouchMode="true"
如果不知道怎樣找到一個在EditText之前的View的話,那你可以直接選擇它的parent (xxxLayout),因為ViewGroup預設的策略是: FOCUS_BEFORE_DESCENDANTS
判斷是否focus
isFocused(), 它判斷自己是否擁有焦點
hasFocus(), 它判斷自己或著自己的child是否擁有焦點 常用
相關文章
- vim 編輯報錯導致無法正常退出和編輯
- ASP.NET - GridView實現點選編輯列ASP.NETView
- [20191218]各種編輯器的退出操作.txt
- Winform DataGridViewTextBoxCell 編輯新增右鍵選單,編輯選中文字ORMView
- AndroidStudio點選兩次返回鍵,退出APPAndroidAPP
- 哈哈:180萬程式設計師不知如何退出Vim編輯器...程式設計師
- 關於EditText焦點監聽
- Cordova + Vue 實現點選兩次退出應用Vue
- 如何將Emacs定義為IntelliJ IDEA的外部編輯器使用?MacIntelliJIdea
- Git Vim編輯器輸入內容、儲存和退出操作Git
- 直播網站原始碼,點選EditText以外的區域,鍵盤隱藏消失網站原始碼
- vue2+editor 編輯器選型Vue
- 線上程式碼編輯器選型
- 自定義jqGrid編輯功能,當行獲取焦點時編輯,失去焦點時儲存
- EditText選擇模式的一些問題模式
- ElementUI表格行編輯單元格編輯支援(輸入框,選擇框)DemoUI
- PDF編輯器首選工具Acrobat Pro DCBAT
- 點選EditText的時候出現被鍵盤遮擋 在不使用scrollView的情況View
- CSDN這編輯器有點強大啊
- [提問交流]ot編輯器寫好文章,再點選編輯出現,插入程式碼段的地方會出現無標題文件
- Android隱藏EditText長按選單中分享功能探索Android
- 編輯
- Spring Boot退出登入注意點Spring Boot
- 基於OpenAI的程式碼編輯器,有點酷有點強!OpenAI
- Shift+Click,編輯[...],如編輯圖片
- 增強 Vim 編輯器,提高編輯效率
- 編輯了
- 文件編輯
- 文章編輯/釋出選擇分類不是很明顯
- 十六進位制編輯器推薦/對比/選用
- 隨處可編輯的編輯器之神VIM
- 一鍵完成php程式碼部署,你還在一點點的編輯?PHP
- Android主介面連續兩次點選物理返回鍵退出應用功能實現Android
- QT6編寫外部庫並呼叫QT
- PyCharm Pro - 提高 Python 編輯開發效率的終 極選擇!PyCharmPython
- 優秀文章有機會被編輯評為ITPUB精選
- Visual Studio 15.8 Preview 3支援多點編輯功能View
- Mac64點陣圖片編輯器——PostworkShop 3 for MacMac
- 編輯距離及編輯距離演算法演算法