【问题】
android的app中,在对于EditText已经实现了:OnFocusChangeListener mFocusChangedListener;
EditText variableValueView = (EditText) variableLayout.findViewById(R.id.variableValue);
EditText variableValueView = (EditText) variableLayout.findViewById(R.id.variableValue);
mFocusChangedListener = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
}else {
}
}
};
而且也是达到预期的,当点击可编辑的EditText时,得到focus,
点击其他(已经被设置为不可编辑,但是可点击,可以获得焦点的)EditText时,焦点是可以失去的。
但是有个问题:
当点击其他(菜单)按钮时,EditText却没有像所希望的失去焦点。
【解决过程】
1.搜:
android edittext not lose focus when click other button
和:
edittext click other not lost focus
参考:
倒是想到:
对于此处,希望的是,点击Menu的菜单的话,则可以对于那些Button或Menu,去复写对应的onClick
事件,然后其中取消掉当前的EditText的焦点(如果当前的焦点是处于在某个EditText上面的话)
应该就可以了。
2.不过,对于此种做法,对于我当前的app来说,还不是最优的做法。
所以,还要先去试试:
把EditText中的值,如果有任何改动,就都调用我此处程序中的validate,然后同时获得反馈,并更新对应的UI(即variable的status)
这样,就不用关系EditText是否获得或失去focus了。
所以去:
3.但是由于此处程序的逻辑有些特殊,会导致死循环,所以暂时放弃上面办法,还是继续此处的办法:
当EditText点击到别的Button或Menu时,让其失去焦点,从而使得变量值可以得到校验是否有效。
然后去看了看,此处不是button,所以没法复写onClick,然后只能在原先的menu的onOptionsItemSelected中去加代码,如下:@Override
public boolean onOptionsItemSelected(MenuItem item) {
//clear current var value EditText focus
View curView = getCurrentFocus();
//if((null != curView) && (curView instanceof EditText) && (curView.isEnabled())){
if(isEditableEditText(curView)){
//being in Edit Mode
curView.clearFocus();
}
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_discard:
...
return true;
case R.id.menu_send:
...
return true;
case R.id.menu_settings:
...
return true;
default:
return super.onOptionsItemSelected(item);
}
}
但是还是不能解决我此处问题:
希望是,在点击了Menu后,在onOptionsItemSelected之前,就能够clear掉之前EditText的focus,
这样才能有机会去validate,然后接着调用到onOptionsItemSelected时,对于R.id.menu_send,才能去执行对应的send的动作,去写入新的值。
4.所以还要再去,找到如何在Menu的onOptionsItemSelected之前,就将EditText的焦点的办法。
搜:
android activity click
和:
android activity onclick event
参考:
另外通过:
找到官网的:
但是却没有找到任何和click有关的
5.参考:
去尝试给ActionBarActionBar(?)中,加上onClick
但是另外搜:
android menu onclick
参考:
是可以给每个menu的item的xml中加上:android:onClick="doThis"
但是很明显,对于每个都加,显得效率很低。
所以暂时不用这个办法。
6.参考:
中的解释:
对于来说,有个:
android:onClickMethod name. The method to call when this menu item is clicked. The method must be declared in the activity as public and accept a
以及对应的示例代码:
android:title="@string/item1"
android:icon="@drawable/group_item1_icon"
android:showAsAction="ifRoom|withText"/>
android:onClick="onGroupItemClick"
android:title="@string/group_item1"
android:icon="@drawable/group_item1_icon" />
android:onClick="onGroupItemClick"
android:title="@string/group_item2"
android:icon="@drawable/group_item2_icon" />
android:title="@string/submenu_title"
android:showAsAction="ifRoom|withText" >
android:title="@string/submenu_item1" />
和:public void onGroupItemClick(MenuItem item) {
// One of the group items (using the onClick attribute) was clicked
// The item parameter passed here indicates which item it is
// All other menu item clicks are handled by onOptionsItemSelected()
}
所以此处就可以去:
将我此处所关心的几个menu的item,弄到一个group中,
然后对于整个的group,弄一个onClick
在其中,做自己需要的处理:clear掉当前EditText的focus
这样估计就可以了。
去试试:
android:id="@+id/menu_discard"
android:icon="@drawable/error_white"
android:orderInCategory="1"
android:showAsAction="ifRoom|withText"
android:onClick="onMenuGroupEditClick"
android:title="@string/discard"/>
android:id="@+id/menu_send"
android:icon="@drawable/forward_white"
android:orderInCategory="2"
android:showAsAction="ifRoom|withText"
android:onClick="onMenuGroupEditClick"
android:title="@string/send"/>
android:id="@+id/menu_settings"
android:icon="@drawable/settings"
android:orderInCategory="3"
android:showAsAction="ifRoom|withText"
android:title="@string/settings"/>
然后去实现。
但是折腾期间,结果发现问题:
代码中的注释:// One of the group items (using the onClick attribute) was clicked
// The item parameter passed here indicates which item it is
// All other menu item clicks are handled by onOptionsItemSelected()
的含义很清楚:
如果此处menu的item实现了自己的onClick,那么,其的确是先于
onOptionsItemSelected
去处理的,但是却导致
onOptionsItemSelected不会被调用了。。。
只会被你自己的onClick事件所处理
所以导致结果是:
即使此处实现了group中的item的onClick事件,那么其中要处理的内容(取消EditText的focus)和后续
类似于onOptionsItemSelected中的switch..case中处理对应item的内容,
也是先后顺序就执行了,中间就没有间隔了。
而这不是我要的,我要的是,先(取消EditText的focus)后(更新对应的值)
中间必须有间隔才行的。。。
7.目前实在很无奈的是,只能去试试:@Override
public boolean onOptionsItemSelected(MenuItem item) {
//clear current var value EditText focus
View curView = getCurrentFocus();
//if((null != curView) && (curView instanceof EditText) && (curView.isEnabled())){
if(isEditableEditText(curView)){
curView.clearFocus();
}
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_discard:
//Toast.makeText(MainActivity.this, "Menu Discard cliked", Toast.LENGTH_SHORT).show();
clearEditedVarValues();
return true;
case R.id.menu_send:
//Toast.makeText(MainActivity.this, "Menu Send cliked", Toast.LENGTH_SHORT).show();
writeEditedVarValues();
return true;
case R.id.menu_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
中的clearFocus,能否直接触发系统事件,从而导致别的相关代码(EditText的OnFocusChangeListener)被调用
然后再回来继续去执行对应的writeEditedVarValues等内容。
结果发现是可以的:
当执行了:curView.clearFocus();
接着会执行到对应的EditText的OnFocusChangeListener的,其中会去执行validate
然后接着可以再执行onOptionsItemSelected中的writeEditedVarValues了。
【总结】
此处,是间接实现最原始的目的:
当点击Menu中的一个子菜单item时,原先的EditText并没有失去焦点
的,办法是:
当点击了Menu的item时,此时去获得当前焦点,判断是所关心的EditText时,再去调用clearFocus去主动失去焦点,即可。