如何使用EditText和ICS实现特定的电话号码格式?

时间:2012-09-26 00:18:17

标签: android android-edittext android-4.0-ice-cream-sandwich

我的应用要求将电话号码格式化为xxx-xxx-xxxx。下面的代码在ICS之前工作,但ICS设备完全忽略格式化文本观察器。为什么它会忽略格式化程序?如何让ICS遵循预期的格式?

我将过滤器和文本侦听器设置为:

final EditText phoneNumber = (EditText) findViewById(R.id.phoneNumber);
phoneNumber.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
phoneNumber.setFilters(new InputFilter[] { new PhoneNumberFilter(), new InputFilter.LengthFilter(12) });

PhoneNumberFilter的代码:

import android.text.InputType;
import android.text.Spanned;
import android.text.method.NumberKeyListener;

public class PhoneNumberFilter extends NumberKeyListener {

    @Override
    public int getInputType() {
        return InputType.TYPE_CLASS_PHONE;
    }

    @Override
    protected char[] getAcceptedChars() {
        return new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' };
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {

        // Don't let phone numbers start with 1
        if (dstart == 0 && source.equals("1")) 
            return "";

        return super.filter(source, start, end, dest, dstart, dend);
    }
}

1 个答案:

答案 0 :(得分:16)

我用以下方法解决了这个问题:

final EditText phoneNumber = (EditText) findViewById(R.id.phoneNumber);
phoneNumber.addTextChangedListener(new PhoneNumberTextWatcher());
phoneNumber.setFilters(new InputFilter[] { new PhoneNumberFilter(), new InputFilter.LengthFilter(12) });

PhoneNumberFilter - 确保电话号码与XXX-XXX-XXXX匹配:

public class PhoneNumberFilter extends NumberKeyListener {

    @Override
    public int getInputType() {
        return InputType.TYPE_CLASS_PHONE;
    }

    @Override
    protected char[] getAcceptedChars() {
        return new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' };
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {

        // Don't let phone numbers start with 1
        if (dstart == 0 && source.equals("1")) 
            return "";

        if (end > start) {
            String destTxt = dest.toString();
            String resultingTxt = destTxt.substring(0, dstart) + source.subSequence(start, end) + destTxt.substring(dend);

            // Phone number must match xxx-xxx-xxxx
            if (!resultingTxt.matches ("^\\d{1,1}(\\d{1,1}(\\d{1,1}(\\-(\\d{1,1}(\\d{1,1}(\\d{1,1}(\\-(\\d{1,1}(\\d{1,1}(\\d{1,1}(\\d{1,1}?)?)?)?)?)?)?)?)?)?)?)?")) { 
                return "";
            }
        }
        return null;
    }
}

PhoneNumberTextWatcher - 处理自动插入破折号并在用户删除时自动删除破折号:

public class PhoneNumberTextWatcher implements TextWatcher {

    private boolean isFormatting;
    private boolean deletingHyphen;
    private int hyphenStart;
    private boolean deletingBackward;

    @Override
    public void afterTextChanged(Editable text) {
        if (isFormatting)
            return;

        isFormatting = true;

        // If deleting hyphen, also delete character before or after it
        if (deletingHyphen && hyphenStart > 0) {
            if (deletingBackward) {
                if (hyphenStart - 1 < text.length()) {
                    text.delete(hyphenStart - 1, hyphenStart);
                }
            } else if (hyphenStart < text.length()) {
                text.delete(hyphenStart, hyphenStart + 1);
            }
        }
        if (text.length() == 3 || text.length() == 7) {
            text.append('-');
        }

        isFormatting = false;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (isFormatting)
            return;

        // Make sure user is deleting one char, without a selection
        final int selStart = Selection.getSelectionStart(s);
        final int selEnd = Selection.getSelectionEnd(s);
        if (s.length() > 1 // Can delete another character
                && count == 1 // Deleting only one character
                && after == 0 // Deleting
                && s.charAt(start) == '-' // a hyphen
                && selStart == selEnd) { // no selection
            deletingHyphen = true;
            hyphenStart = start;
            // Check if the user is deleting forward or backward
            if (selStart == start + 1) {
                deletingBackward = true;
            } else {
                deletingBackward = false;
            }
        } else {
            deletingHyphen = false;
        }
    }

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