【问题】
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
参考:
android – make EditText lose focus on clicking a button – Stack Overflow
android – editText is not losing focus – Stack Overflow
倒是想到:
对于此处,希望的是,点击Menu的菜单的话,则可以对于那些Button或Menu,去复写对应的
onClick
事件,然后其中取消掉当前的EditText的焦点(如果当前的焦点是处于在某个EditText上面的话)
应该就可以了。
2.不过,对于此种做法,对于我当前的app来说,还不是最优的做法。
所以,还要先去试试:
把EditText中的值,如果有任何改动,就都调用我此处程序中的validate,然后同时获得反馈,并更新对应的UI(即variable的status)
这样,就不用关系EditText是否获得或失去focus了。
所以去:
【记录】把Android中的EditText的值变成如有改动就调用相关处理代码(validate校验输入是否合法)
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
参考:
android – When to implement Activity-wide click event? – Stack Overflow
另外通过:
getting a click event on an activity – Google Groups
找到官网的:
但是却没有找到任何和click有关的
5.参考:
Input Events | Android Developers
去尝试给ActionBarActionBar(?)中,加上onClick
但是另外搜:
android menu onclick
参考:
android – actionbar menu item onclick? – Stack Overflow
是可以给每个menu的item的xml中加上:
android:onClick="doThis"
但是很明显,对于每个都加,显得效率很低。
所以暂时不用这个办法。
6.参考:
Menu Resource | Android Developers
中的解释:
对于<item>
来说,有个:
android:onClick MenuItem as its only parameter, which indicates the item clicked. This method takes precedence over the standard callback to onOptionsItemSelected() . See the example at the bottom. |
以及对应的示例代码:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item1" android:title="@string/item1" android:icon="@drawable/group_item1_icon" android:showAsAction="ifRoom|withText"/> <group android:id="@+id/group"> <item android:id="@+id/group_item1" android:onClick="onGroupItemClick" android:title="@string/group_item1" android:icon="@drawable/group_item1_icon" /> <item android:id="@+id/group_item2" android:onClick="onGroupItemClick" android:title="@string/group_item2" android:icon="@drawable/group_item2_icon" /> </group> <item android:id="@+id/submenu" android:title="@string/submenu_title" android:showAsAction="ifRoom|withText" > <menu> <item android:id="@+id/submenu_item1" android:title="@string/submenu_item1" /> </menu> </item> </menu>
和:
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
这样估计就可以了。
去试试:
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <group android:id="@+id/menu_group_edit"> <item android:id="@+id/menu_discard" android:icon="@drawable/error_white" android:orderInCategory="1" android:showAsAction="ifRoom|withText" android:onClick="onMenuGroupEditClick" android:title="@string/discard"/> <item android:id="@+id/menu_send" android:icon="@drawable/forward_white" android:orderInCategory="2" android:showAsAction="ifRoom|withText" android:onClick="onMenuGroupEditClick" android:title="@string/send"/> </group> <item android:id="@+id/menu_settings" android:icon="@drawable/settings" android:orderInCategory="3" android:showAsAction="ifRoom|withText" android:title="@string/settings"/> </menu>
然后去实现。
但是折腾期间,结果发现问题:
代码中的注释:
// One of the group items (using the onClick attribute) was clicked // 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去主动失去焦点,即可。