背景
有一个需求,比方说下图:
点击了上图的Image 区域才可以编辑。
那么我首先想到的就是:
android:focusable="false"
不让它获取到焦点不就ok吗?
事实上这是很好的方式,然后我开始编辑点击图片后EditText获取焦点:
editText.setSelection(editText.getText().length());//设置焦点位置移到最后,如果没有这一句,那么焦点将会在最前
editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.requestFocus();// 请求焦点
ps:
editText.setFocusable(true); //物理按键可获得焦点,一般智能电视机,我们的遥控操作之类
editText.setFocusableInTouchMode(true); ////触摸可获得焦点
上述如果有一个不为true,android系统都会认为不能获取焦点。
出现了一个小小的问题,拥有焦点后,居然没有弹出软键盘。这时候开发者主动点,把它盘出来。
InputMethodManager inputManager=(InputMethodManager)getBaseContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(editText,InputMethodManager.SHOW_FORCED);
这样似乎ok了的。
那么糟糕的情况来了,当我点击EditText的以外的地方的时候,焦点还在Edit上面,焦点并没有消失。
解决方案
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
View edittext=findViewById(R.id.edittext);
//判断是否被点击
if (!isTouchPointInView(edittext,(int) ev.getX(),(int) ev.getY()))
{
edittext.clearFocus();
}
break;
}
return super.dispatchTouchEvent(ev);
}
我通过判断如果不在触摸区域内,就让它失去焦点。
按照这个想法,我的确成功了,然而凡事哪有一帆风顺,我遭遇到了另外一个bug。那就是,焦点失去了,然而软键盘还在。
这时候我想到了焦点变动事件,code 如下:
findViewById(R.id.edittext).setOnFocusChangeListener(new View.OnFocusChangeListener(){
@Override
public void onFocusChange(View v,boolean hasFocus)
{
EditText editText=(EditText)v;
if (!hasFocus)
{
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}
}
});
是的,失去了焦点那么就让软键盘消失。
其他需要注意的
其他问题,比如页面back了,或者退出了app,我们都需要手动去让软键盘隐藏,事件分别是@Override的:onStop与onBackPressed。