1. 程式人生 > >Android 文本監聽接口TextWatcher詳解

Android 文本監聽接口TextWatcher詳解

n) sta listener ret vertical ear top ica lock

TextWatcher是一個用來監聽文本變化的接口,使用該接口可以很方便的對可顯示文本控件和可編輯文本控件中的文字進行監聽和修改

TextWatcher接口中定義了三個方法:


public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

該方法在文本改變之前調用,傳入了四個參數:

  • CharSequence s:文本改變之前的內容
  • int start:文本開始改變時的起點位置,從0開始計算
  • int count:要被改變的文本字數,即將要被替代的選中文本字數
  • int after:改變後添加的文本字數,即替代選中文本後的文本字數

該方法調用是在文本沒有被改變,但將要被改變的時候調用,把四個參數組成一句話就是:
在當前文本s中,從start位置開始之後的count個字符(即將)要被after個字符替換掉


public void onTextChanged(CharSequence s, int start, int before, int count) {}

該方法是在當文本改變時被調用,同樣傳入了四個參數:

  • CharSequence s:文本改變之後的內容
  • int start:文本開始改變時的起點位置,從0開始計算
  • int before:要被改變的文本字數,即已經被替代的選中文本字數
  • int count:改變後添加的文本字數,即替代選中文本後的文本字數

該方法調用是在文本被改變時,改變的結果已經可以顯示時調用,把四個參數組成一句話就是:
在當前文本s中,從start位置開始之後的before個字符(已經)被count個字符替換掉了


public void afterTextChanged(Editable s) {}

該方法是在文本改變結束後調用,傳入了一個參數:

  • Editable s:改變後的最終文本

該方法是在執行完beforeTextChanged、onTextChanged兩個方法後才會被調用,此時的文本s為最終顯示給用戶看到的文本。我們可以再對該文本進行下一步處理,比如把文本s顯示在UI界面上


實踐

使用TextWatcher監聽EditText剩余可輸入文本字數

有個這樣的需求:用戶在EditText中只能輸入50個字符,在用戶輸入的同時在UI界面中告訴用戶還可輸入多少個字符
布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical">

    <!-- 文字輸入框 -->
    <EditText
        android:id="@+id/edt_text_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:background="@drawable/bg_edit_radius"
        android:gravity="top"
        android:maxLength="50"
        android:minLines="5"
        android:padding="10dp"
        android:textColor="@android:color/white"
        android:textSize="20sp"
        />

    <!-- 已輸入字數 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="已輸入字數:"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_text_now_sum"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="#ff0000"
            android:textSize="16sp"/>
    </LinearLayout>

    <!-- 剩余可輸入 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="剩余可輸入:"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_text_remain"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="50"
            android:textColor="#ff0000"
            android:textSize="16sp"/>
    </LinearLayout>

</LinearLayout>

在以上布局中,EditText控件使用maxLength=”50”限制可輸入字符為50個

需要使用的控件和變量

    /** 輸入框 */
    private EditText mTextContentEdt;

    /** 剩余字數 */
    private TextView mTextRemainTv;

    /** 已輸入字數 */
    private TextView mTextNowSumTv;

    /** 總可輸入字數 */
    private int textRemainAll = 50;

輸入框樣式圖片bg_edit_radius.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="1dp"
        android:color="@android:color/black" />
    <corners android:radius="10dp" />
    <solid android:color="@android:color/darker_gray" />
</shape>

初始化界面

/**
 * 初始化界面
 */
private void initUI() {
      setContentView(R.layout.activity_main);
      mTextContentEdt = (EditText) findViewById(R.id.edt_text_content);
      mTextRemainTv = (TextView) findViewById(R.id.tv_text_remain);
      mTextNowSumTv = (TextView) findViewById(R.id.tv_text_now_sum);
}

給EditText添加監聽,MyTextWatcher類為我們自定義的監聽類

/**
 * 初始化監聽
 */
 private void initListener() {
      mTextContentEdt.addTextChangedListener(new MyTextWatcher());
 }

創建一個自定義的TextWatcher監聽類,實現TextWatcher接口

/**
 * 創建自己的TextWatcher監聽類
 */
private class MyTextWatcher 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) {
      // 已經輸入的字數
      mTextNowSumTv.setText(String.valueOf(s.length()));
      // 剩余可輸入字數
      int remainSum = textRemainAll - s.length();
      mTextRemainTv.setText(String.valueOf(remainSum));
 }

  @Override
 public void afterTextChanged(Editable s) {

 }
}

運行後的效果圖

技術分享圖片

Android 文本監聽接口TextWatcher詳解