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

【workaround】Android中如何使得EditText在已经被Disable的情况下还能够获得焦点

Android crifan 3053浏览 0评论

【问题】

android中,对于EditText来说,

想要实现效果:

在已经设置了Disable->不允许编辑的情况下

但是允许获得焦点->这样就可以被点击而获得焦点->别的可编辑的EditText就可以失去焦点->代码中有会相应失去焦点的处理

代码中设置如下:

		//update for focusable or not
		if(varIsEditable){
			//deprecated
			variableValueView.setEnabled(true);
	        variableValueView.setFocusable(true);
	        variableValueView.setFocusableInTouchMode(true);
	        
	        variableValueView.setOnFocusChangeListener(mFocusChangedListener);
		}
		else{
			variableValueView.setEnabled(false);
			variableValueView.setFocusable(true);
			variableValueView.setFocusableInTouchMode(true);

			//variableValueView.setOnFocusChangeListener(null);
			variableValueView.setOnFocusChangeListener(mFocusChangedListener);
			variableValueView.setKeyListener(null);
		}

但是结果却不起效果:

对于已经设置Enable为false的EditText

点击后,还是无法获得焦点。

【折腾过程】

1.参考:

setEnabled() vs setClickable(), what is the difference? : Android Community – For Application Development

看看EditText是否有setClickable,发现是有的,所以去打开:

		//update for focusable or not
		if(varIsEditable){
			//deprecated
			variableValueView.setEnabled(true);
	        variableValueView.setFocusable(true);
	        variableValueView.setFocusableInTouchMode(true);
	        
	        variableValueView.setOnFocusChangeListener(mFocusChangedListener);
		}
		else{
			variableValueView.setEnabled(false);
			variableValueView.setClickable(true);
			variableValueView.setFocusable(true);
			variableValueView.setFocusableInTouchMode(true);

			//variableValueView.setOnFocusChangeListener(null);
			variableValueView.setOnFocusChangeListener(mFocusChangedListener);
			variableValueView.setKeyListener(null);
		}

结果是:

问题依旧。

2.参考:

android – Disable EditText editability and focus (like TextView) – Stack Overflow

还是没用。

3.最后是采用了别的办法,去实现了所需要的效果:

确保EditText不可编辑的情况下,然后可以接收到点击事件(触屏事件)。

所用代码如下:

(1)代码中,设置不可编辑的EditText为Enable,但是setKeyListener为null

这样就无法输入,达到不允许编辑的效果了

接着再去设置setOnTouchListener,保证触屏后,可以进行后续处理

 

		//update for focusable or not
		if(varIsEditable){
			//deprecated
			variableValueView.setEnabled(true);
	        variableValueView.setFocusable(true);
	        variableValueView.setFocusableInTouchMode(true);
	        
	        variableValueView.setOnFocusChangeListener(mFocusChangedListener);
		}
		else{
			//variableValueView.setEnabled(false);
			variableValueView.setEnabled(true);
			variableValueView.setClickable(true);
			variableValueView.setFocusable(true);
			variableValueView.setFocusableInTouchMode(true);

			//variableValueView.setOnFocusChangeListener(null);
			variableValueView.setOnFocusChangeListener(mFocusChangedListener);
			variableValueView.setKeyListener(null);

			//variableValueView.setOnClickListener(mClickListener);
			variableValueView.setOnTouchListener(mTouchListener);
		}

(2)然后去实现对应的:OnTouchListener

	OnFocusChangeListener mFocusChangedListener;
	OnClickListener mClickListener;
	OnTouchListener mTouchListener;
    
		mTouchListener = new OnTouchListener(){
			@Override
			public boolean onTouch(View v, MotionEvent me) {
				if(isNonEditableEditText(v)){
					//is non-editable EditText
					EditText nonEditableEditText = (EditText)v;
					View curView = getWindow().getCurrentFocus();
					if(isEditableEditText(curView)){
						//is editable EditText
						EditText curEditText = (EditText)curView;
						//clear focus
						//curEditText.clearFocus();
	            		
						//hidden inputmethod keyboard
	            		//getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
	            		InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
	            		imm.hideSoftInputFromWindow(curEditText.getWindowToken(), 0);

	            		nonEditableEditText.requestFocus();
					}
				}
				return true;
			}
		};

在其中去处理:

当触屏后:

先去判断是否为可编辑的EditText

	private boolean isEditableEditText(View v){
		boolean isEditable = false;
		EditText editText = null;
		if(v != null){
			if(v instanceof EditText){
				editText = (EditText)v;
				if(null != editText.getKeyListener()){
					isEditable = true;
				}
			}
		}
		return isEditable;
	}

	private boolean isNonEditableEditText(View v){
		boolean isNonEditable = false;
		EditText editText = null;
		if(v != null){
			if(v instanceof EditText){
				editText = (EditText)v;
				if(null == editText.getKeyListener()){
					isNonEditable = true;
				}
			}
		}
		
		return isNonEditable;
	}

可见,此处不是通过Enable去判断是否为可编辑的

->因为调试期间发现,如果

variableValueView.setEnabled(false);

则会导致后续的

			variableValueView.setClickable(true);
			variableValueView.setFocusable(true);
			variableValueView.setFocusableInTouchMode(true);

都失效,从而导致无法监听对应的Click或Touch事件了。

所以此处才逼得只能先去Enable,然后再去设置setKeyListener(null)的;

此处是通过判断getKeyListener是否为空来确定是否可编辑的。

 

这样,就很凑合地,去实现了:

当点击了,不可编辑的EditText,可以捕获事件,

然后去处理后续事情的:

此处是:

隐藏当前获得的EditText,其是可编辑的,隐藏掉输入法;

然后对于新点击的,不可编辑的EditText,去获得对应的焦点;

 

这样后续在onFocusChange中:

	    mFocusChangedListener = new OnFocusChangeListener() {
	        @Override
	        public void onFocusChange(View v, boolean hasFocus) {
	        	String labelStr = "";

	        	if(AppConfig.getInstance().isDebugMode()){
		            RelativeLayout parentView = (RelativeLayout)v.getParent();
		        	//LinearLayout parentView = (LinearLayout)v.getParent().getParent();
		        	//LinearLayout parentView = (LinearLayout)v.getParent().getParent().getParent();
		            TextView labelView = (TextView) parentView.findViewById(R.id.variableLabel);
		            labelStr = (String) labelView.getText();
	        	}

	            if(hasFocus){
	                //enter into edittext
	            	if(AppConfig.getInstance().isDebugMode()){
		                //Toast.makeText(getApplicationContext(), "got focus: " + v.toString(), Toast.LENGTH_LONG).show();
	            		Toast.makeText(getApplicationContext(), "got focus: " + labelStr, Toast.LENGTH_SHORT).show();
	            		
	            		updateCurrentMode();
	            	}
	            	else{
	            		//when some EditText got focus, then should into EditMode
	            		updateCurrentMode();
	            	}
	            }else {
	            	EditText valueView = (EditText)v;

	                //left edittext
	            	if(AppConfig.getInstance().isDebugMode()){
		                //Toast.makeText(getApplicationContext(), "lost focus: " + v.toString(), Toast.LENGTH_LONG).show();
	            		//for debug
	            		Toast.makeText(getApplicationContext(), "lost focus: " + labelStr, Toast.LENGTH_SHORT).show();
	            		
	            		updateCurrentMode();
	            	}
	            	else{
		                if(valueView.isEnabled()){
		                    //only validate new value for editable value
		                    if(mVarValueViewVarNameMap.containsKey(valueView)){
		                        String varName = mVarValueViewVarNameMap.get(valueView);
		                        String varValue = (String)valueView.getText().toString();
		                        DeviceModelManager.getInstance().getCurrentDeviceModel().postValidateVariablesValue(varName, varValue);
		                    }
		                }
	            	}
	            }
	        }
	    };

就可以执行对应的更新状态的事情了。

 

【总结】

目前还是无法实现:

在设置EditText为disable,不可编辑的情况下,获得焦点。

只能规避此问题,先EditText设置为Enable,然后setKeyListener为null,然后后续实现对应的Click或Touch的Listener去执行自己所需要的效果。。。

很是挫啊。。。

转载请注明:在路上 » 【workaround】Android中如何使得EditText在已经被Disable的情况下还能够获得焦点

发表我的评论
取消评论

表情

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

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