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

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

Android crifan 3159浏览 0评论

【问题】

android中,对于EditText来说,

想要实现效果:

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

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

代码中设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//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,发现是有的,所以去打开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//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,保证触屏后,可以进行后续处理

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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去判断是否为可编辑的

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

1
variableValueView.setEnabled(false);

则会导致后续的

1
2
3
variableValueView.setClickable(true);
variableValueView.setFocusable(true);
variableValueView.setFocusableInTouchMode(true);

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

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

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

 

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

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

然后去处理后续事情的:

此处是:

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

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

 

这样后续在onFocusChange中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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.316 seconds, using 22.18MB memory