问题:SearchView 在退出软键盘后,Focus依然存在的问题。并且还会抢其它控件Focus?在试过clearFocus后也依然不好使...
分析:原来当前焦点并不在SearchView 上,而是在它内部的 SearchAutoComplete mQueryTextView 上,所以SreachView clearFoucus没有效果。
这是SearchView 设置焦点的代码,其中调用了 mQueryTextView.requestFocus(direction, previouslyFocusedRect);
/** @hide */
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
// Don't accept focus if in the middle of clearing focus
if (mClearingFocus) return false;
// Check if SearchView is focusable.
if (!isFocusable()) return false;
// If it is not iconified, then give the focus to the text field
if (!isIconified()) {
boolean result = mQueryTextView.requestFocus(direction, previouslyFocusedRect);
if (result) {
updateViewsVisibility(false);
}
return result;
} else {
return super.requestFocus(direction, previouslyFocusedRect);
}
}
解决:
我要拿到mQueryTextView并且调用clearFocus(); 然后在调用SearchView.clearFocus();
首先监听软键盘弹起状态:view.getViewTreeObserver().addOnGlobalLayoutListener(); //通过给根布局View注册布局监听器
获取当前焦点所在View,判断是否是SearchView$SearchAutoComplete ,然后根据软键盘状态与当前焦点View,控制SearchView的焦点位置
Code:
void regeKeyListener(final View v) {
// 注册根View布局监听,监听布局大小改变
v.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
// 获取当前焦点所在View
View currentFocus = getActivity().getCurrentFocus();
String name = currentFocus.getClass().getName();
Rect outRect = new Rect();
v.getWindowVisibleDisplayFrame(outRect);
// 计算比例,从而判断软键盘是否弹起
double dl = 1.0 * outRect.bottom / v.getMeasuredHeight();
if (dl < 0.8 && name.equals("android.widget.SearchView$SearchAutoComplete")) {
if (!isKeyUp) {
isKeyUp = true;
}
} else if (isKeyUp) {
currentFocus.clearFocus();
mSearchView.clearFocus();
isKeyUp = false;
}
}
});
}
效果: