40

In my android application I need to disable Spacebar only. But I didn't find a solution for this problem. I need to disable space bar and when user enter space should not work; special characters, letters, digits and all other - should work. What I tried is:

etPass.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // TODO Auto-generated method stub
        String str = s.toString();
        if(str.length() > 0 && str.contains(" ")) {
            etPass.setError("Space is not allowed");
            etPass.setText("");
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub
    }

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

But the problem here is once space comes whole text is deleting.

I removed etPass.setText("");, so at that time error message is showing, but at that time user can still able to type space. But what I need is user shouldn't able to type the space.

SerjantArbuz
  • 982
  • 1
  • 12
  • 16
roshanpeter
  • 1,334
  • 3
  • 13
  • 32

16 Answers16

83

This solution worked for me :

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
android:inputType="textFilter"

Add it into edit text in the XML file

Alireza Noorali
  • 3,129
  • 2
  • 33
  • 80
SAndroidD
  • 1,745
  • 20
  • 33
43

Why don't you think about a character filter .. Here is a sample code snippet.

/* To restrict Space Bar in Keyboard */
InputFilter filter = new InputFilter() {
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {
        for (int i = start; i < end; i++) {
            if (Character.isWhitespace(source.charAt(i))) {
                return "";
            }
        }
        return null;
    }

};
input.setFilters(new InputFilter[] { filter });
Don Chakkappan
  • 7,397
  • 5
  • 44
  • 59
  • 10
    Why it is deleting the text if i am clicking the space bar to give white spaces? – Akshay kumar May 03 '17 at 08:28
  • @Akshaykumar that bug must be related to something else. Code provided is working fine here. – thijsonline May 22 '17 at 15:01
  • 7
    This approach has very strange side effect (if suggestions are enabled for this EditText) - tapping space triggers like backspace. 1st entered space in the end of EditText really filters out, but next space tappings works like backspace erasing entered text which is totally weird. To avoid this side effect you could use inputType="textVisiblePassword" - with this workaround it will work. – Stan Nov 10 '17 at 08:10
  • 1
    if you press multiple times to space it erases the last char – Arutha Nov 21 '18 at 13:55
  • Why not just this at the beginning if (source.toString().equals(" ")) return ""; – dharmendra Feb 11 '19 at 07:42
19

This version support input from keyboard's suggestions with spaces.

InputFilter filter = new InputFilter() {
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String filtered = "";
        for (int i = start; i < end; i++) {
            char character = source.charAt(i);
            if (!Character.isWhitespace(character)) {
                filtered += character;
            }
        }

        return filtered;
    }

};

input.setFilters(new InputFilter[] { filter });

PS: Kotlin version:

input.filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
    source.toString().filterNot { it.isWhitespace() }
})
Kevin Robatel
  • 8,025
  • 3
  • 44
  • 57
  • 9
    This approach has very strange side effect if suggestions are enabled for this EditText - if user taps BackSpace the whole entered text doubles in EditText. So instead of erasing text just grows up. Thats kinda annoying. – Stan 5 mins ago – Stan Nov 10 '17 at 08:00
  • Kotlin filter is creating issue, it's removing max length configuration for password type EditText. – CoDe Jan 11 '19 at 11:34
  • @kevin This kotlin filter is not working in samsung devices, is there any solutions for samsung devices – Om Bala Mar 13 '19 at 15:36
6

I found very better solution instead of use digit or write any extra code , just do this things...

tiePassword.filters = tiePassword.filters.let {
        it + InputFilter { source, _, _, _, _, _ ->
            source.filterNot { char -> char.isWhitespace() }
        }
    }

it will not allow any space. try and enjoy... keep Learning and sharing

Rajesh Satvara
  • 3,842
  • 2
  • 30
  • 50
5

Try this

Use android:digits don't include " "(space in it)

<EditText
    android:inputType="number"
    android:digits="0123456789.abcdefghijklmnl....."// write character that you want to allow
/>
N J
  • 27,217
  • 13
  • 76
  • 96
5
EditText yourEditText = (EditText) findViewById(R.id.yourEditText);
yourEditText.setFilters(new InputFilter[] {
    @Override
    public CharSequence filter(
        CharSequence cs, int start, int end,
        Spanned spanned, int dStart, int dEnd
    ) {
        /** For backspace */
        if (cs.equals("") {
             return cs;
        }

        /** Here is no space character */
        if (cs.toString().matches("[a-zA-Z]+")) {
            return cs;
        }

        return "";
    }
});
SerjantArbuz
  • 982
  • 1
  • 12
  • 16
johnrao07
  • 6,690
  • 4
  • 32
  • 55
5

I tried using the InputFilter solution and doesn't work for me because If try to tap backspace, the whole entered text doubles in the EditText.

This solution works for me in Kotlin using TextWatcher:

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

    override fun afterTextChanged(p0: Editable?) {
        val textEntered = editText.text.toString()

        if (textEntered.isNotEmpty() && textEntered.contains(" ")) {
            editText.setText(editText.text.toString().replace(" ", ""));
            editText.setSelection(editText.text!!.length);
        }
    }})
Peter
  • 2,654
  • 2
  • 33
  • 44
pableiros
  • 14,932
  • 12
  • 99
  • 105
5

Extension for remove spaces:

fun String.removeSpace() = trim().replace("\\s+".toRegex(), replacement = "")

Remove spaces for EditText enter:

val removeFilter = InputFilter { s, _, _, _, _, _ -> s.toString().removeSpace() }
editText.apply { filters = filters.plus(removeFilter) }
SerjantArbuz
  • 982
  • 1
  • 12
  • 16
4

In afterTextChanged method put the following code:

public void afterTextChanged(Editable s) {
    String str = etPass.getText().toString();
    if (str.length() > 0 && str.contains(" ")) {
        etPass.setText(etPass.getText().toString().replaceAll(" ",""));
        etPass.setSelection(etPass.getText().length());
    }
}
SerjantArbuz
  • 982
  • 1
  • 12
  • 16
Moti
  • 462
  • 2
  • 6
  • 18
  • working fine when enter space at last in an edittext but when entering space in between texts, the after space texts in editext gets disappeared, any solution for this problem @Moti – Om Bala Apr 04 '19 at 07:34
  • I checked this now, and it's not happened to me :\ @OmBala – Moti Apr 04 '19 at 09:19
  • 1
    Found out what is the issue @Moti, we have give TYPE_TEXT_FLAG_NO_SUGGESTIONS in input type – Om Bala Apr 04 '19 at 15:38
4

Try this and it works well

Kotlin:

editText.filters = arrayOf(object : InputFilter {
    override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? {
        // eliminates single space
        if (end == 1) {
            if (Character.isWhitespace(source?.get(0)!!)) {
                return ""
            }
        }
        return null
    }
})

Java:

editText.setFilters(new InputFilter[]{(source, start, end, dest, dstart, dend) -> {
    if (end == 1) {
        if (Character.isWhitespace(source.charAt(0))) {
            return "";
        }
    }
    return null;
}});
SerjantArbuz
  • 982
  • 1
  • 12
  • 16
Shyam Kumar
  • 909
  • 11
  • 12
2

Just replace this in your code and it should work perfectly,

etPass.setText(etPass.getText().toString().replaceAll(" ",""));
etPass.setSelection(etPass.getText().length());
Madhur
  • 3,303
  • 20
  • 29
  • and yout can move cursor at end using this `editText.setSelection(editText.getText().toString().length()` – alizeyn Jan 30 '18 at 06:55
1

To disable space use

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (editclicked) {
        if (keyCode == KeyEvent.KEYCODE_SPACE) {
            return false
        }
    } else {
        super.onKeyDown(keyCode, event);
    }
}
Jithin Sunny
  • 3,352
  • 4
  • 26
  • 42
0

instead of etPass.setText(""); just remove space from EditText data.

etPass.setText(etPass.getText().toString().trim());
etPass.setSelection(autoComplete.getText().length());

so your IF condition will be as follows :

if(str.length() > 0 && str.contains(" "))
{
    etPass.setError("Space is not allowed");
    etPass.setText(etPass.getText().toString().trim());
    etPass.setSelection(etPass.getText().length());
}
Ravi
  • 34,851
  • 21
  • 122
  • 183
0

So far I discovered that this depends a lot on your keyboard which will change behavior based on return values and even delete characters assuming the last one was inserted. Also, SwiftKey may ignore textNoSuggestions, so I ended up using this InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD

etInput.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
etInput.filters = arrayOf(InputFilter { source, start, end, dest, dstart, dend ->
    //val debugMsg = "'" + source + "' (" + start + " - " + end + ") '" + dest + "' (" + dstart + " - " + dend + ")"
    val srcChangeLength = end - start
    if (srcChangeLength <= 0) { //We're deleting a character
        //Log.d("idk", debugMsg + " -> '" + source + "'")
        return@InputFilter source
    }
    val result = if (source is SpannableStringBuilder) source else {
        //Log.d("idk", "Converted source from " + source::class.qualifiedName)
        SpannableStringBuilder(source)
    }
    for (i in end - 1 downTo start) {
        val currentChar = result[i]
        if (Character.isSpaceChar(currentChar)) {
            result.delete(i, i+1) //NOTE: You must modify or return the source. Otherwise,
            //android assumes you're inserting a string and saves the changes for the next callback(?)
        }
    }
    //Log.d("idk", debugMsg + " -> '" + result + "'")
    return@InputFilter result
})

I'm not an expert on this so I may have the wrong assumptions here, but this is working so far for me.

Isaac Paul
  • 1,959
  • 2
  • 15
  • 20
0

The vast majority of answers do not consider the issue with the input buffer, which can cause duplicate input when the input method is in buffer mode. Here is my solution:

internal val AvoidSpaceFilter = InputFilter { source, _, _, _, _, _ ->
    val sourceText = source.toString()
    if (" " !in sourceText) return@InputFilter null // keep original
    sourceText.replace(" ", "")
}

etUsername.apply { filters += AvoidSpaceFilter }

This solution also handles pasting from the clipboard, by simply excluding scenarios where the input source does not contain any spaces.

twiceYuan
  • 863
  • 8
  • 11
0

Try this, it worked for me

editText.addTextChangedListener(new TextWatcher() {
private boolean mSpaceDisabled = false;

@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 (mSpaceDisabled) {
        mSpaceDisabled = false;
        return;
    }

    String input = s.toString();
    StringBuilder filtered = new StringBuilder();
    for (int i = 0; i < input.length(); i++) {
        char c = input.charAt(i);
        if (c == ' ') {
            mSpaceDisabled = true;
            continue;
        }
        filtered.append(c);
    }

    editText.removeTextChangedListener(this);
    editText.setText(filtered.toString());
    editText.setSelection(filtered.length());
    editText.addTextChangedListener(this);
}

});

kashinath
  • 1
  • 2