EditText: Differentiate between text change by setText() or by keyboard input

前端 未结 5 729
一个人的身影
一个人的身影 2021-01-04 01:58

I have an EditText View which is edited by setText() from my code and by the user via (soft/hard) keyboard and - if possible by speech input. I wan

相关标签:
5条回答
  • 2021-01-04 02:15

    You can use a flag to differentiate.

    ((EditText) rootView.findViewById(R.id.editText1)).addTextChangedListener(new TextWatcher() {
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            }
    
            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            }
    
            public void afterTextChanged(Editable editable) {
                update(true);
            }
        });            
    
    private boolean updating = false;
    
    private void update(boolean multiply) {
        if(updating){
            return;
        }
        updating = true;
        EditText editText1 = (EditText) getView().findViewById(R.id.editText1);
        editText1.setText("XXX");
        updating = false;
    }
    
    0 讨论(0)
  • 2021-01-04 02:19

    There are already a lot of good workarounds here! I wanted to add what worked for me to give options to whoever might be having this issue in the future.

    I used the TextWatcher and simply relied on checking for what element currently has focus when the EditText is being edited. Note that this would work if in your app, the user has to give focus to the EditText (by clicking on it for instance) before entering a text, and you're sure that another element will have the focus when you're using setText in your code.

    Something like this

    yourEditText.addTextChangedListener(
                new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                    }
    
                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        if (yourEditText.hasFocus) {
                            //this is a user input
                        }
                    }
    
                    @Override
                    public void afterTextChanged(Editable s) {
    
                    }
                }
        );
    
    0 讨论(0)
  • 2021-01-04 02:26

    I was having this issue when rotating the device. My editText is inside a dialog. Here's how I solved it:

    editText.addTextChangedListener(
        new TextWatcher() {
    
            @Override
            public void afterTextChanged(Editable s) {
                String newValue = s.toString();
    
               String oldValue = (String) editText.getTag();
    
                if (newValue.length() > 0) {
                    editText.setTag(newValue);
                }
    
                boolean itReallyChanged = oldValue != null && !newValue.equals(oldValue) && !newValue.isEmpty();
                if (itReallyChanged) {
                    // Pretty sure the user genuinely changed this value,
                    // not the device rotation
                }
            }
        }
    );
    
    0 讨论(0)
  • 2021-01-04 02:33

    I believe android do not let you to distinguash between programmatically and manually entered text. The only workaround fo you as to use some sla that will indicate when test was set by your code, because you are always know when you call setText().

    0 讨论(0)
  • 2021-01-04 02:34

    I finally solved the problem by implementing a InputConnectionWrapper (see this question and particularly the answer for an implementation example) which has various methods to get the input from a soft-keyboard. I return my InputConnectionWrapper in the method EditText.onCreateInputConnection(). For hard keyboards I use EditText.onPreIme(). All these methods are overwritten and route their input through my framework which handles the text input and updates the View accordingly. This means, in all these overwritten methods (except for onCreateInputConnection()) the super method is not called cause I update the View myself. This prevents inconsistencies between my data model and the View.

    0 讨论(0)
提交回复
热议问题