最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】android中点击其他的(如Button等)但是EditText却没有失去焦点

Android crifan 6571浏览 0评论

【问题】

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

找到官网的:

Activity | Android Developers

但是却没有找到任何和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
Method name. The method to call when this menu item is clicked. The method must be declared in the activity as public and accept a 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

// 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去主动失去焦点,即可。

转载请注明:在路上 » 【已解决】android中点击其他的(如Button等)但是EditText却没有失去焦点

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.168 seconds, using 22.09MB memory