android format edittext to display spaces after ev

2020-02-10 14:48发布

Android - I want to get a number input from the user into an EditText - it needs to be separated by spaces - every 4 characters. Example: 123456781234 -> 1234 5678 1234

This is only for visual purpose. However i need the string without spaces for further usage.

What is the easiest way I can do this?

10条回答
孤傲高冷的网名
2楼-- · 2020-02-10 15:21

You need to use TextWatcher to achieve visual purpose spaces.

And use any simply split string by space logic to join it back or loop through the entire string per character wise and eliminate (char) 32 from the string

查看更多
再贱就再见
3楼-- · 2020-02-10 15:21

Format of text is 000 000 0000

android edittext textwatcher format phone number like xxx-xxx-xx-xx

public class PhoneNumberTextWatcher implements TextWatcher {

private static final String TAG = PhoneNumberTextWatcher.class
        .getSimpleName();
private EditText edTxt;
private boolean isDelete;

public PhoneNumberTextWatcher(EditText edTxtPhone) {
    this.edTxt = edTxtPhone;
    edTxt.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_DEL) {
                isDelete = true;
            }
            return false;
        }
    });
}

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

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

public void afterTextChanged(Editable s) {

    if (isDelete) {
        isDelete = false;
        return;
    }
    String val = s.toString();
    String a = "";
    String b = "";
    String c = "";
    if (val != null && val.length() > 0) {
        val = val.replace(" ", "");
        if (val.length() >= 3) {
            a = val.substring(0, 3);
        } else if (val.length() < 3) {
            a = val.substring(0, val.length());
        }
        if (val.length() >= 6) {
            b = val.substring(3, 6);
            c = val.substring(6, val.length());
        } else if (val.length() > 3 && val.length() < 6) {
            b = val.substring(3, val.length());
        }
        StringBuffer stringBuffer = new StringBuffer();
        if (a != null && a.length() > 0) {
            stringBuffer.append(a);
            if (a.length() == 3) {
                stringBuffer.append(" ");
            }
        }
        if (b != null && b.length() > 0) {
            stringBuffer.append(b);
            if (b.length() == 3) {
                stringBuffer.append(" ");
            }
        }
        if (c != null && c.length() > 0) {
            stringBuffer.append(c);
        }
        edTxt.removeTextChangedListener(this);
        edTxt.setText(stringBuffer.toString());
        edTxt.setSelection(edTxt.getText().toString().length());
        edTxt.addTextChangedListener(this);
    } else {
        edTxt.removeTextChangedListener(this);
        edTxt.setText("");
        edTxt.addTextChangedListener(this);
    }

}
}
查看更多
叼着烟拽天下
4楼-- · 2020-02-10 15:22

I have created a class that encapsulates the given behavior.

/**
 * Custom [TextWatcher] class that appends a given [separator] for every [interval].
 */
abstract class SeparatorTextWatcher(
    private val separator: Char,
    private val interval: Int
) : TextWatcher {

    private var dirty = false
    private var isDelete = false

    override fun afterTextChanged(editable: Editable?) {
        if (dirty) return

        dirty = true
        val text = editable.toString().handleSeparator()
        onAfterTextChanged(text)
        dirty = false
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        // Empty
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        isDelete = before != 0
    }

    private fun String.handleSeparator(): String {
        val stringBuilder = StringBuilder(this)

        if (length > 0 && length.rem(interval + 1) == 0) {
            if (isDelete) {
                stringBuilder.deleteCharAt(length - 1)
            } else {
                stringBuilder.insert(length - 1, separator)
            }
        }

        return stringBuilder.toString()
    }

    /**
     * Subclasses must implement this method to get the formatted text.
     */
    abstract fun onAfterTextChanged(text: String)
}

Here's a snippet on how to use it:

editText.addTextChangedListener(object : SeparatorTextWatcher(' ', 4) {
            override fun onAfterTextChanged(text: String) {
                editText.run {
                    setText(text)
                    setSelection(text.length)
                }
            }
        })
查看更多
成全新的幸福
5楼-- · 2020-02-10 15:28

Simple Answer

    YourEditText.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) {

            int len=s.toString().length();

            if (before == 0 && (len == 4 || len == 9 || len == 14 ))
                YourEditText.append(" ");
        }

        @Override
        public void afterTextChanged(Editable s) {


        }
    });
查看更多
乱世女痞
6楼-- · 2020-02-10 15:34

is this editext for credit card?
first create count variable

int count = 0;

then put this in your oncreate(activity) / onviewcreated(fragment)

    ccEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, 
                                          int count, int after) { /*Empty*/}

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

        @Override
        public void afterTextChanged(Editable s) {

        int inputlength = ccEditText.getText().toString().length();

            if (count <= inputlength && inputlength == 4 || 
                inputlength == 9 || inputlength == 14)){

                ccEditText.setText(ccEditText.getText().toString()+" ");

                int pos = ccEditText.getText().length();
                ccEditText.setSelection(pos);

            } else if(count >= inputLength &&(inputLength == 4 ||
                     inputLength == 9 || inputLength == 14)){
                ccEditText.setText(ccEditText.getText().toString()
                                   .substring(0,ccEditText.getText()
                                   .toString().length()-1));

                int pos = ccEditText.getText().length();
                ccEditText.setSelection(pos);
            }
            count = ccEditText.getText().toString().length();
        }
    });
查看更多
在下西门庆
7楼-- · 2020-02-10 15:37

Assuming that you know the final length of the String, you could implement a TextWatcher this way:

override fun setUp(view: View?) {

    editText.addTextChangedListener(object : TextWatcher{
        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }

        override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {
            if(p2 == 0 && (p0.length == 4 || p0.length == 9 || p0.length == 14))
                editText.append(" ")
        }

        override fun afterTextChanged(p0: Editable?) {
        }
    })

You just add a space each 4-digits block. p2 == 0 is to assure the user is not deleting, otherwise he/she would get stock.

The code is in Kotlin, You can do it exactly the same way in Java.

查看更多
登录 后发表回答