【问题标题】:EditText: Differentiate between text change by setText() or by keyboard inputEditText:通过 setText() 或键盘输入区分文本更改
【发布时间】:2011-06-15 14:21:38
【问题描述】:

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

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

【问题讨论】:

    标签: android input android-edittext


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 是的,我也想到了一个布尔指示变量,但是 setText() 和用户输入可能同时发生,所以不能正常工作。
      • 但是为什么需要区分不同的输入来源呢?
      • 正如我上面解释的,我想在用户更改某些文本时触发一个事件。但是,如果文本被代码更改,则不得触发此事件。
      • 如果不锁定 EditText,您将无法实现所需的功能,但我不确定是否允许。
      • 尝试结合 onTextChangedListener 和 flag。只要所有编辑都在一个线程内进行,onTextChangedListener 事件将被排队,您可以尝试分析标志。
      【解决方案3】:

      这里已经有很多好的解决方法了!我想添加对我有用的东西,以便为将来可能遇到此问题的人提供选择。

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

      类似的东西

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

      【讨论】:

        【解决方案4】:

        您可以使用标志来区分。

        ((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;
        }
        

        【讨论】:

          【解决方案5】:

          我在旋转设备时遇到了这个问题。我的 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
                      }
                  }
              }
          );
          

          【讨论】:

          • 真的变了吗? :)
          猜你喜欢
          • 2012-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-01
          • 2018-11-28
          • 1970-01-01
          相关资源
          最近更新 更多