6

TextWatcherを使用したEditTextがあります。テキストを5'9"のような人間の身長にフォーマットすることになっています。しかし、ユーザーが間違えて入力ミスのある文字を削除したい場合、TextWatherはそれを許可しません。たとえば、ユーザーが「文字」を削除したいとします。 TextWatherはすぐにその背中を追加します。以下はコードです。では、ユーザーがEditTextのテキストを削除できるようにするにはどうすればよいですか?

private class CustomTextWatcher implements TextWatcher {
    private EditText mEditText;

public CustomTextWatcher(EditText e) {
    mEditText = e;
}

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

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


}

public void afterTextChanged(Editable s) {
    int count = s.length();
    String str = s.toString();
    if (count == 1) {
        str = str + "'";
    } else if (count == 3) {
        str = str + "\"";
    } else if ((count > 4) && (str.charAt(str.length() - 1) != '\"')) {
        str = str.substring(0, str.length() - 2)
                + str.charAt(str.length() - 1) + "\"";
    } else {
        return;
    }
    mEditText.setText(str);
    mEditText.setSelection(mEditText.getText().length());


}

}

4

2 に答える 2

8

コードが間違ったコールバックにあることについてKarakuriが投稿した事実を無視して、ユーザーが使用するキーを聞くだけの簡単な修正を追加できます。

実際のテストや既存のコードのさらなる改善がなければ、これで説明されている問題が修正されるようです。

package com.example.testwatchertest;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;

public class MainActivity extends Activity implements TextWatcher {

    EditText editText;
    boolean keyDel = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
        editText.addTextChangedListener(this);

        editText.setOnKeyListener(new OnKeyListener() {

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (keyCode == KeyEvent.KEYCODE_DEL){
                    keyDel = true;
                }else{
                    keyDel = false;
                }
                return false;
            }
        });

    }

    @Override
    public void afterTextChanged(Editable s) {
        // 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 onTextChanged(CharSequence s, int start, int before, int count) {

        if (!keyDel) {

            String str = s.toString();
            if (count == 1) {
                str = str + "'";
            } else if (count == 3) {
                str = str + "\"";
            } else if ((count > 4) && (str.charAt(str.length() - 1) != '\"')) {
                str = str.substring(0, str.length() - 2) + str.charAt(str.length() - 1) + "\"";
            } else {
                return;
            }
            editText.setText(str);
            editText.setSelection(editText.getText().length());

        }

    }

}
于 2012-12-28T16:17:12.350 に答える
2

ドキュメントから

public abstract void onTextChanged(CharSequence s、int start、int before、int count)

このメソッドは、s内で、開始から始まるカウント文字が、以前の長さの古いテキストを置き換えたことを通知するために呼び出されます。このコールバックからsに変更を加えようとするとエラーになります。

他の2つのコールバックではなく、afterTextChanged()で変更を加える必要があります。

public abstract void afterTextChanged(Editable s)

このメソッドは、s内のどこかでテキストが変更されたことを通知するために呼び出されます。このコールバックからsにさらに変更を加えることは正当ですが、変更を加えるとこのメソッドが再帰的に再度呼び出されるため、無限ループに陥らないように注意してください。(他のafterTextChanged()方法ですでに他の変更が行われ、オフセットが無効になっている可能性があるため、変更が行われた場所はわかりません。ただし、ここで知る必要がある場合は、でを使用 setSpan(Object, int, int, int)onTextChanged(CharSequence, int, int, int)て場所をマークし、ここからスパンが終了した場所を検索できます。上。)

于 2012-12-28T16:11:49.573 に答える