EditText:通过setText()或键盘输入区分文本更改

问题描述 投票:16回答:5

我有一个EditText视图,由setText()从我的代码和用户通过(软/硬)键盘编辑 - 如果可能的话,通过语音输入。我希望以不同于普通用户输入的方式处理我的代码所做的输入:如果发生用户输入,则应触发内部事件。但我不知道如何区分两者。以前 - 在模拟器上开发时 - 我使用onKeyDown()方法来捕获用户输入。但是,当在真实设备上进行测试时,我发现onKeyDown()不是从软键盘输入触发的。此外,语音输入不会被识别,但我认为这是一个小缺陷。所以这个解决方案对我来说别无选择。

另一方面,有onTextChanged()方法,但这是由setText()和键盘输入触发。那么如何区分两者或哪种方法仅由用户输入调用,而不是在使用setText()时,我可以覆盖它吗?

android input android-edittext
5个回答
5
投票

我终于通过实现InputConnectionWrapper(参见this问题,尤其是实现示例的答案)解决了这个问题,该问题有各种方法可以从软键盘获取输入。我用InputConnectionWrapper方法返回我的EditText.onCreateInputConnection()。对于硬键盘,我使用EditText.onPreIme()。所有这些方法都被覆盖并通过我的框架路由它们的输入,框架处理文本输入并相应地更新View。这意味着,在所有这些覆盖的方法(onCreateInputConnection()除外)中,不会调用super方法,因为我自己更新了View。这可以防止我的数据模型和视图之间的不一致。


4
投票

我相信android不会让你区分编程和手动输入的文本。你可以使用一些sla来解决你的代码设置测试的唯一方法,因为你总是知道你什么时候调用setText()。


2
投票

您可以使用标志来区分。

((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
投票

我在旋转设备时遇到了这个问题。我的editText在对话框中。这是我解决它的方式:

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
投票

这里已经有很多很好的解决方法了!我想补充一些对我有用的东西,为将来可能遇到这个问题的人提供选择。

我使用了TextWatcher,并且只是在编辑EditText时依赖于检查当前具有焦点的元素。请注意,如果在您的应用中,用户必须在输入文本之前将焦点放在EditText上(例如通过单击它),并且您确定在使用setText时另一个元素将具有焦点在你的代码中。

像这样的东西

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) {

                }
            }
    );
© www.soinside.com 2019 - 2024. All rights reserved.