11

而不是 5118710,它应该是511-8710。我想在用户已经在 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);
            }

        }
4

7 回答 7

37

最直接的解决方案是使用PhoneNumberFormattingTextWatcherwhich 将根据系统区域设置格式化数字。

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());
于 2013-06-07T03:00:24.243 回答
11

实施以下修改addTextChangedListenertxt_HomeNo. 下面的代码正在检查输入的文本的长度是否为 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
    }
});
于 2013-06-07T05:53:56.763 回答
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());
                }
            }
        }
于 2017-01-25T10:52:37.243 回答
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]", "");
    }
于 2017-08-30T12:05:19.277 回答
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)

于 2016-06-16T19:32:27.130 回答
0

通过使用 OnEditTextChangedListener 自己做,并通过计算字符数插入破折号,在 EditText Changed Listener 中计数字符

于 2013-06-07T02:35:11.280 回答
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]", "");
    }
}
于 2018-06-14T19:36:54.137 回答