【问题标题】:How to use the TextWatcher class in Android?如何在 Android 中使用 TextWatcher 类?
【发布时间】:2012-01-22 12:39:58
【问题描述】:

谁能告诉我如何屏蔽EditText 中的子字符串 或如何将EditText 子字符串输入更改为密码类型替换 由另一个 字符 像这样 123xxxxxxxxx3455

 String contents = et1.getText().toString();
 et1.setText(contents.replace.substring(0, contents.length()-2),"*");

请告诉我如何在 Android 中使用 TextWatcher 方法。

【问题讨论】:

    标签: android android-edittext textwatcher


    【解决方案1】:

    TextWatcher使用...

    et1.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
    
            // TODO Auto-generated method stub
        }
    
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
            // TODO Auto-generated method stub
        }
    
        @Override
        public void afterTextChanged(Editable s) {
    
            // TODO Auto-generated method stub
        }
    });
    

    【讨论】:

    • 如何处理这个 TextWatcher?提供更多细节以便更好地理解。
    • 在被文本观察者覆盖的方法中。你可以掩盖你真正想要的文字。
    • 但我不知道如何使用 TextWatcher,你能用小例子解释一下吗?谢谢你的指导
    • 将此代码放入 java..一旦用户输入文本,将调用方法之一...根据函数的名称。
    • 其实如果是这样的话最好不要使用文本观察器。它会无限循环
    【解决方案2】:

    TextWatcher接口有3个回调方法,当文本发生变化时,它们都按以下顺序调用:

    beforeTextChanged(CharSequence s, int start, int count, int after)
    
    • 在更改应用到文本之前调用
      s 参数是应用任何更改之前的文本
      start 参数是文本中更改部分开头的位置
      count 参数是自start 位置以来s 序列中更改部分的长度
      after 参数是新序列的长度,它将替换s 序列中从startstart+count 的部分。
      不得更改此方法中TextView 中的文本(使用myTextView.setText(String newText))。
    onTextChanged(CharSequence s, int start, int before, int count)`
    
    • 类似于beforeTextChanged 方法,但在文本更改后调用。
      s 参数是应用更改后的文本
      start 参数与beforeTextChanged 方法中的参数相同。
      count参数是beforeTextChanged方法中的after参数。
      before参数就是beforeTextChanged方法中的count参数。
      不得更改此方法中TextView 中的文本(使用myTextView.setText(String newText))。
    afterTextChanged(Editable s)
    
    • 可以通过此方法更改TextView 中的文本。
      /!\ 警告:当您更改TextView 中的文本时, TextWatcher 将再次被触发,开始无限循环。然后,您应该添加类似 boolean _ignore 的属性,以防止无限循环。
      示例:
    new TextWatcher() {
            boolean _ignore = false; // indicates if the change was made by the TextWatcher itself.
    
            @Override
            public void afterTextChanged(Editable s) {
                if (_ignore)
                    return;
    
                _ignore = true; // prevent infinite loop
                // Change your text here.
                // myTextView.setText(myNewText);
                _ignore = false; // release, so the TextWatcher start to listen again.
            }
    
            // Other methods...
    }
    

    总结:


    即用型类:TextViewListener

    就我个人而言,我制作了自定义文本侦听器,它为我提供了单独字符串中的 4 个部分,这对我来说使用起来更加直观。

     /**
       * Text view listener which splits the update text event in four parts:
       * <ul>
       *     <li>The text placed <b>before</b> the updated part.</li>
       *     <li>The <b>old</b> text in the updated part.</li>
       *     <li>The <b>new</b> text in the updated part.</li>
       *     <li>The text placed <b>after</b> the updated part.</li>
       * </ul>
       * Created by Jeremy B.
       */
      
      public abstract class TextViewListener implements TextWatcher {
        /**
         * Unchanged sequence which is placed before the updated sequence.
         */
        private String _before;
      
        /**
         * Updated sequence before the update.
         */
        private String _old;
      
        /**
         * Updated sequence after the update.
         */
        private String _new;
      
        /**
         * Unchanged sequence which is placed after the updated sequence.
         */
        private String _after;
      
        /**
         * Indicates when changes are made from within the listener, should be omitted.
         */
        private boolean _ignore = false;
      
        @Override
        public void beforeTextChanged(CharSequence sequence, int start, int count, int after) {
            _before = sequence.subSequence(0,start).toString();
            _old = sequence.subSequence(start, start+count).toString();
            _after = sequence.subSequence(start+count, sequence.length()).toString();
        }
      
        @Override
        public void onTextChanged(CharSequence sequence, int start, int before, int count) {
            _new = sequence.subSequence(start, start+count).toString();
        }
      
        @Override
        public void afterTextChanged(Editable sequence) {
            if (_ignore)
                return;
      
            onTextChanged(_before, _old, _new, _after);
        }
      
        /**
         * Triggered method when the text in the text view has changed.
         * <br/>
         * You can apply changes to the text view from this method
         * with the condition to call {@link #startUpdates()} before any update,
         * and to call {@link #endUpdates()} after them.
         *
         * @param before Unchanged part of the text placed before the updated part.
         * @param old Old updated part of the text.
         * @param aNew New updated part of the text?
         * @param after Unchanged part of the text placed after the updated part.
         */
        protected abstract void onTextChanged(String before, String old, String aNew, String after);
      
        /**
         * Call this method when you start to update the text view, so it stops listening to it and then prevent an infinite loop.
         * @see #endUpdates()
         */
        protected void startUpdates(){
            _ignore = true;
        }
      
        /**
         * Call this method when you finished to update the text view in order to restart to listen to it.
         * @see #startUpdates()
         */
        protected void endUpdates(){
            _ignore = false;
        }
      }
    

    例子:

    myEditText.addTextChangedListener(new TextViewListener() {
            @Override
            protected void onTextChanged(String before, String old, String aNew, String after) {
               // intuitive use of parameters
               String completeOldText = before + old + after;
               String completeNewText = before + aNew + after;
               
               // update TextView
                startUpdates(); // to prevent infinite loop.
                myEditText.setText(myNewText);
                endUpdates();
            }
    }
    

    【讨论】:

    • 这段代码的问题是光标不会停留在它应该是或者至少这是我的经验。
    • 是不是textview调用了这些方法
    • 我想是的
    • 以这种方式修复光标问题:protected void onTextChanged(String before, String old, String aNew, String after, Editable sequence)
    【解决方案3】:

    补充答案

    这是对其他答案的视觉补充。我对代码和解释的更完整答案是here

    • 红色:即将删除(替换)的文本
    • 绿色:刚刚添加的文本(替换旧的红色文本)

    【讨论】:

      【解决方案4】:

      对于 Kotlin 使用 KTX 扩展 功能: (它使用TextWatcher 作为之前的答案)

      yourEditText.doOnTextChanged { text, start, count, after -> 
              // action which will be invoked when the text is changing
          }
      


      导入core-KTX:

      implementation "androidx.core:core-ktx:1.2.0"
      

      【讨论】:

        【解决方案5】:

        解决方案的更大视角:

        @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                View v = inflater.inflate(R.layout.yourlayout, container, false);
                View tv = v.findViewById(R.id.et1);
                ((TextView) tv).addTextChangedListener(new TextWatcher() {
                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                         SpannableString contentText = new SpannableString(((TextView) tv).getText());
                         String contents = Html.toHtml(contentText).toString();
                    }
        
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        
                        // TODO Auto-generated method stub
                    }
        
                    @Override
                    public void afterTextChanged(Editable s) {
        
                        // TODO Auto-generated method stub
                    }
                });
                return v;
            }
        

        这对我有用,我第一次这样做。

        【讨论】:

          【解决方案6】:

          在 Android 中使用 TextWatcher

          这是一个示例代码。尝试使用TextView的addTextChangedListener方法

          addTextChangedListener(new TextWatcher() {
          
                  BigDecimal previousValue;
                  BigDecimal currentValue;
          
                  @Override
                  public void onTextChanged(CharSequence s, int start, int before, int
                          count) {
                      if (isFirstTimeChange) {
                          return;
                      }
                      if (s.toString().length() > 0) {
                          try {
                              currentValue = new BigDecimal(s.toString().replace(".", "").replace(',', '.'));
                          } catch (Exception e) {
                              currentValue = new BigDecimal(0);
                          }
                      }
                  }
          
                  @Override
                  public void beforeTextChanged(CharSequence s, int start, int count,
                          int after) {
                      if (isFirstTimeChange) {
                          return;
                      }
                      if (s.toString().length() > 0) {
                          try {
                              previousValue = new BigDecimal(s.toString().replace(".", "").replace(',', '.'));
                          } catch (Exception e) {
                              previousValue = new BigDecimal(0);
                          }
                      }
                  }
          
                  @Override
                  public void afterTextChanged(Editable editable) {
                      if (isFirstTimeChange) {
                          isFirstTimeChange = false;
                          return;
                      }
                      if (currentValue != null && previousValue != null) {
                          if ((currentValue.compareTo(previousValue) > 0)) {
                              //setBackgroundResource(R.color.devises_overview_color_green);
                              setBackgroundColor(flashOnColor);
                          } else if ((currentValue.compareTo(previousValue) < 0)) {
                              //setBackgroundResource(R.color.devises_overview_color_red);
          
                              setBackgroundColor(flashOffColor);
                          } else {
                              //setBackgroundColor(textColor);
                          }
                          handler.removeCallbacks(runnable);
                          handler.postDelayed(runnable, 1000);
                      }
                  }
              });
          

          【讨论】:

            【解决方案7】:

            创建自定义 TextWatcher 子类:

            public class CustomWatcher implements TextWatcher {
            
                private boolean mWasEdited = false;
            
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            
                }
            
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
            
                }
            
                @Override
                public void afterTextChanged(Editable s) {
            
                    if (mWasEdited){
            
                        mWasEdited = false;
                        return;
                    }
            
                    // get entered value (if required)
                    String enteredValue  = s.toString();
            
                    String newValue = "new value";
            
                    // don't get trap into infinite loop
                    mWasEdited = true;
                    // just replace entered value with whatever you want
                    s.replace(0, s.length(), newValue);
            
                }
            }
            

            为您的 EditText 设置监听器:

            mTargetEditText.addTextChangedListener(new CustomWatcher());
            

            【讨论】:

            • 这实际上是一种聪明、轻量级的解决问题的方法!谢谢!
            • 无法将使用 JVM 目标 1.8 构建的字节码内联到使用 JVM 目标 1.6 构建的字节码中。请指定正确的“-jvm-target”选项
            【解决方案8】:
                public class Test extends AppCompatActivity {
            
                EditText firstEditText;
                EditText secondEditText;
            
                @Override
                protected void onCreate(@Nullable Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.test);
                    firstEditText = (EditText)findViewById(R.id.firstEditText);
                    secondEditText = (EditText)findViewById(R.id.secondEditText);
            
                    firstEditText.addTextChangedListener(new EditTextListener());
            
                }
            
                private class EditTextListener implements 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) {
                        secondEditText.setText(firstEditText.getText());
                    }
            
                    @Override
                    public void afterTextChanged(Editable s) {
                    }
                }
            }
            

            【讨论】:

              【解决方案9】:

              如果您使用对话框编辑文本来实现。像这样使用:。用于其他编辑文本也是如此。

              dialog.getInputEditText().addTextChangedListener(new TextWatcher() {
                  @Override
                  public void beforeTextChanged(CharSequence charSequence, int start, int before, int count) {
                  }
              
                  @Override
                  public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                      if (start<2){
                              dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
                          }else{
                              double size =  Double.parseDouble(charSequence.toString());
                              if (size > 0.000001 && size < 0.999999){
                                  dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
                              }else{
                                  ToastHelper.show(HistoryActivity.this, "Size must between 0.1 - 0.9");
                                  dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
                              }
              
                          }
                  }
              
                  @Override
                  public void afterTextChanged(Editable editable) {
              
                  }
              });
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2023-03-24
                • 2012-12-18
                • 1970-01-01
                • 2012-10-04
                • 2019-01-11
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多