在安卓系统中自动添加电话号码的破折号

11

应该是511-8710而不是5118710。我想在用户已经在EditText中输入了3个数字后添加一个破折号。 EditText的最大长度仅为7个数字。

当我解决了上述问题之后,又遇到了编码问题。当我已经输入了3个数字时,它会追加破折号(这就是我想要发生的),但我的问题在于下一个3个数字也会追加破折号(像这样:511-871-...请帮帮我。谢谢!

    txt_HomeNo.addTextChangedListener(new TextWatcher() {

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

            boolean flag = true;
            String eachBlock[] = txt_HomeNo.getText().toString().split("-");
            for (int i = 0; i < eachBlock.length; i++) {
                if (eachBlock[i].length() > 3) {
                    flag = false;
                }
            }

            if (flag) {

                txt_HomeNo.setOnKeyListener(new OnKeyListener() {

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

                        if (keyCode == KeyEvent.KEYCODE_DEL)
                            keyDel = 1;
                        return false;
                    }
                });

                if (keyDel == 0) {

                    if (((txt_HomeNo.getText().length() + 1) % 4) == 0) {

                        if (txt_HomeNo.getText().toString().split("-").length <= 3) {
                            txt_HomeNo.setText(txt_HomeNo.getText() + "-");
                            txt_HomeNo.setSelection(txt_HomeNo.getText().length());
                        }
                    }
                    a = txt_HomeNo.getText().toString();
                } else {
                    a = txt_HomeNo.getText().toString();
                    keyDel = 0;
                }

            } else {
                txt_HomeNo.setText(a);
            }

        }

谢谢 @neo108,但是我该如何让它变成"3位数-4位数"呢?因为代码逻辑是设置为4位数-4位数的。 - user2400937
请问您能否发一下您目前的代码以格式化数字? - neo108
嗨,neo108,请参考上面的代码。谢谢! - user2400937
https://dev59.com/F1HTa4cB1Zd3GeqPVNyk#37187857 - HenryChuang
7个回答

37
最直接的解决方案是使用PhoneNumberFormattingTextWatcher,它会根据系统语言环境格式化号码。
XML:
<EditText
    android:id="@+id/phone_number"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/enter_phone_number"
    android:inputType="phone" />
在你的类中添加addTextChangedListener()
EditText phoneNumber = (EditText)findViewById(R.id.phone_number);
phoneNumber.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

但是这种方法只适用于 xxx-xxx-xxxx 的格式吗? - mike20132013
@mike20132013,格式取决于目标设备当前使用的系统区域设置。 - ozbek
明白了,现在更有意义了。 - mike20132013
如此充满希望且易于实现! - Keith

11

实现以下对txt_HomeNo的修改后的addTextChangedListener。下面的代码检查输入文本的长度是否为3,如果是,则添加-。这不是一个非常健壮的解决方案,但它能够工作!

txt_HomeNo.addTextChangedListener(new TextWatcher() {

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

        txt_HomeNo.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (keyCode == KeyEvent.KEYCODE_DEL)
                    keyDel = 1;
                return false;
            }
        });

        if (keyDel == 0) {
            int len = txt_HomeNo.getText().length();
            if(len == 3) {
                txt_HomeNo.setText(txt_HomeNo.getText() + "-");
                txt_HomeNo.setSelection(txt_HomeNo.getText().length());
            }
        } else {
            keyDel = 0;
        }
    }

    @Override
    public void afterTextChanged(Editable arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub
    }
});

1
太好了!我已经成功让它工作了,如果您在邮政编码中输入了6个数字,它会自动插入缺失的连字符。 - Phil
我正在尝试在我的应用程序中实现这段代码,但是我的代码中出现了“无法解析符号'keyDel'”的错误。 我没有看到该变量在上面的代码片段中声明。 有关此问题的任何帮助? - Kevin Bright
我找到了问题所在。您需要在addTextChangedListener方法中声明一个变量int keyDel。现在它可以工作了,尽管如果您添加两个连字符并通过两个连字符进行退格,则连字符不会正确地添加回来。例如,我将if(len == 3)更改为if(len == 2 || len == 6),以在第2和第6位数字后添加连字符。这很好地起作用,即使是退格键也可以正常工作,如果您只删除一个连字符。但是,如果您删除了两个连字符并重新开始输入,则新文本不会正确添加连字符。如果您删除整个editText字段,则连字符确实有效。 - Kevin Bright
非常感谢您添加了破折号,但我还需要在按下退格键时将其删除...请帮助我解决这个问题... - Bali
但是不同的设备可能不支持KeyEvent.KEYCODE_DEL。例如,我的三星设备可以使用它,但华硕设备无法使用。 - Ramesh Bhati

5

我对neo108的解决方案有一些小修改,以便它可以同时适用于软键盘和硬键盘。例如,在我的代码中,edittext将遵循自动在第5和第9位置添加“ ”的规则。

txtPhone.addTextChangedListener(new TextWatcher() {

        int keyDel;

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            txtPhone.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        keyDel = 1;
                    }
                    return false;
                }
            });

            String currentString = txtPhone.getText().toString();
            int currentLength = txtPhone.getText().length();

            if (currentLength == 5 || currentLength == 9) {
                keyDel = 1;
            }

            if (keyDel == 0) {
                if (currentLength == 4 || currentLength == 8) {
                    txtPhone.setText(txtPhone.getText() + " ");
                    txtPhone.setSelection(txtPhone.getText().length());
                }
            } else {
                if (currentLength != 5 && currentLength != 9) {
                    keyDel = 0;
                } else if ((currentLength == 5 || currentLength == 9)
                        && !" ".equals(currentString.substring(currentLength - 1, currentLength))) {
                    txtPhone.setText(currentString.substring(0, currentLength - 1) + " "
                            + currentString.substring(currentLength - 1, currentLength));
                    txtPhone.setSelection(txtPhone.getText().length());
                }
            }
        }

4

我实现了一个自定义的TextWatcher;这个类可以处理10位和11位的电话号码(例如1-555-867-5309555-867-5309)。允许添加、删除、插入、批量删除,同时保持正确的光标位置。

    public class CustomPhoneTextWatcher implements TextWatcher {

    private final EditText editText;
    private String previousString;

    public CustomPhoneTextWatcher(EditText editText) {
        this.editText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        // if the previous editable ends with a dash and new is shorter than previous
        // additionally remove preceding character
        if (previousString != null && previousString.endsWith("-") && editable.toString().length() < previousString.length()) {
            previousString = editable.toString();
            String removedCharacterPriorToDash = editable.toString().substring(0, editable.length() - 1);
            editText.setText(removedCharacterPriorToDash);
            int position = editText.length();
            Editable etext = editText.getText();
            Selection.setSelection(etext, position);
        } else {
            previousString = editable.toString();
            String numericString = StringUtils.removeNonnumeric(editable.toString());
            int stringLength = numericString.length();
            boolean startsWithOne = numericString.startsWith("1");
            numericString = numericString.substring(0, Math.min(stringLength, 10 + (startsWithOne ? 1 : 0)));

            int lastHyphenIndex = 6 + (startsWithOne ? 1 : 0);
            int secondToLastHyphenIndex = 3 + (startsWithOne ? 1 : 0);

            if (stringLength >= lastHyphenIndex) {
                numericString = numericString.substring(0, lastHyphenIndex) + "-" + numericString.substring(lastHyphenIndex, numericString.length());
            }
            if (stringLength >= secondToLastHyphenIndex) {
                numericString = numericString.substring(0, secondToLastHyphenIndex) + "-" + numericString.substring(secondToLastHyphenIndex, numericString.length());
            }
            if (numericString.startsWith("1")) {
                numericString = numericString.substring(0, 1) + "-" + numericString.substring(1, numericString.length());
            }
            if (!numericString.equals(editable.toString())) {
                editText.setText(numericString);
                int position = editText.length();
                Editable etext = editText.getText();
                Selection.setSelection(etext, position);
            }
        }
    }
}

StringUtils.removeNonnumeric(editable.toString()) 是调用这个方法:

   public static String removeNonnumeric(String text) {
        return text.replaceAll("[^\\d]", "");
    }

这个有几个问题: 1)如果你在键盘上选择“-”,它会删除文本。当你到达空字符串的情况时,它会崩溃。 2)如果你按住删除键,删除会被中断。 我添加了一个实现,使用了下面一些你的代码,解决了我遇到的这些问题。 - Ryan Newsom

1

感谢以上所有答案。

  • 当您的设备仅有软键盘时,editText.setOnKeyListener()将永远不会被调用。
  • 如果我们严格遵循添加"-"的规则,则此代码并不总是显示所需结果。

    editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

但是上述代码是格式化电话号码的最佳解决方案。

除了上述解决方案,我编写了一段代码,可适用于所有情况:

phoneNumber.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) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            if (len > phoneNumber.getText().length() ){
                len--;
                return;
            }
            len = phoneNumber.getText().length();

            if (len == 4 || len== 8) {
                String number = phoneNumber.getText().toString();
                String dash = number.charAt(number.length() - 1) == '-' ? "" : "-";
                number = number.substring(0, (len - 1)) + dash + number.substring((len - 1), number.length());
                phoneNumber.setText(number);
                phoneNumber.setSelection(number.length());
            }
        }
    });

这行代码需要在数字的第3和第6位添加"-"如果(len == 4 || len == 8)

0
import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;

/**
 * Auto-formats a number using -.
 * Ex. 303-333-3333
 * Ex. 1-303-333-3333
 * Doesn't allow deletion of just -
 */
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
    private static final String TAG = "PhoneNumberTextWatcher";

    private final EditText editText;
    private String previousNumber;

    /**
     * Indicates the change was caused by ourselves.
     */
    private boolean mSelfChange = false;

    public PhoneNumberFormattingTextWatcher(EditText editText) {
        this.editText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        // if the previous editable ends with a dash and new is shorter than previous
        // additionally remove preceding character
        Log.i(TAG, "Previous String: " + previousNumber);

        //if self change ignore
        if (mSelfChange) {
            Log.i(TAG, "Ignoring self change");
            mSelfChange = false;
            return;
        }

        String phoneNumber = removeNonnumeric(editable.toString());
        int stringLength = phoneNumber.length();

        //empty case
        if(stringLength == 0) {
            mSelfChange = true;
            editText.setText("");
            return;
        }

        boolean startsWithOne = phoneNumber.charAt(0) == '1';
        int maxLength = 10 + (startsWithOne ? 1 : 0);

        //too large
        if(stringLength > maxLength) {
            Log.i(TAG, "String length is greater than max allowed, using previous string: " + previousNumber);
            mSelfChange = true;
            editText.setText(previousNumber);
            Editable etext = editText.getText();
            Selection.setSelection(etext, previousNumber.length());
            return;
        }

        phoneNumber = formatPhoneNumber(phoneNumber);

        if(previousNumber != null && phoneNumber.length() == previousNumber.length()) {
            //user deleting last character, and it is a -
            if(phoneNumber.endsWith("-")) {
                phoneNumber = phoneNumber.substring(0, phoneNumber.length()-2);
            }
        }

        mSelfChange = true;
        previousNumber = phoneNumber;
        editText.setText(phoneNumber);
        Editable etext = editText.getText();
        Selection.setSelection(etext, phoneNumber.length());
    }

    private String formatPhoneNumber(String phoneNumber) {
        int stringLength = phoneNumber.length();
        //check if starts with 1, if it does, dash index is increased by 1
        boolean startsWithOne = phoneNumber.charAt(0) == '1';

        //if the length of the string is 6, add another dash
        int lastHyphenIndex = 6 + (startsWithOne ? 1 : 0);
        if (stringLength >= lastHyphenIndex) {
            phoneNumber = phoneNumber.substring(0, lastHyphenIndex) + "-" + phoneNumber.substring(lastHyphenIndex, phoneNumber.length());
        }
        //if the length of the string is 3, add a dash
        int secondToLastHyphenIndex = 3 + (startsWithOne ? 1 : 0);
        if (stringLength >= secondToLastHyphenIndex) {
            phoneNumber = phoneNumber.substring(0, secondToLastHyphenIndex) + "-" + phoneNumber.substring(secondToLastHyphenIndex, phoneNumber.length());
        }
        //If the number starts with 1, add a dash after 1
        if (phoneNumber.startsWith("1")) {
            phoneNumber = phoneNumber.substring(0, 1) + "-" + phoneNumber.substring(1, phoneNumber.length());
        }

        return phoneNumber;
    }

    private static String removeNonnumeric(String text) {
        return text.replaceAll("[^\\d]", "");
    }
}

previousNumber will throw a NullPointerException - Otieno Rowland

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接