8

I have an edittext, and a textwatcher that watches if SPACE arrived or not. If its a SPACE I would like to delete that instantly. Or if its a space I want to make sure it doesnt appear but indicate somehow (seterror, toast) for the user that space is not allowed.

edittext.addTextChangedListener(new TextWatcher() {

    public void afterTextChanged(Editable s) {

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

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

I cannot define onkeydown in the afterTextChaned method, since it gives me an error.

 public boolean onKeyDown(int keyCode, KeyEvent event) {
                super.onKeyDown(keyCode, event);

                if (keyCode == KeyEvent.KEYCODE_SPACE) {

                }
    }

So it is not working (syntax error, misplaced construct for the int keyCode.

Thanks you in advance!

Jani Bela
  • 1,660
  • 4
  • 27
  • 50
  • what'd the error you mentioned? – dldnh Mar 18 '12 at 11:47
  • No error in the logcat, it is a simple syntax error. – Jani Bela Mar 18 '12 at 11:51
  • Do you want to show the entered space character `then` delete it or do you simply want to make sure the user doesn't enter spaces in the `EditText`? – user Mar 18 '12 at 13:29
  • I want to make sure the user doesnt enter space, but if it happens I want to make an error message appear for the edittext (a seterror message). I my case its not obvious that SPACE cannot be used, so I would like to warn the user if he/she uses SPACE. – Jani Bela Mar 18 '12 at 15:21

7 Answers7

48

The solution is as usually much simpler:

@Override
public void afterTextChanged(Editable s) {
    String result = s.toString().replaceAll(" ", "");
    if (!s.toString().equals(result)) {
         ed.setText(result);
         ed.setSelection(result.length());
         // alert the user
    }
}

This shouldn't have the problems of the previous attempts.

user
  • 86,916
  • 18
  • 197
  • 190
  • Ok, how about this, I'll just paste `this line with spaces` inside the textbox? Huh, now what? :D (I'm not trying to be mean, :) I am not sure so I'm asking...You might want to check the entire string for spaces. – st0le Mar 18 '12 at 15:42
  • @st0le My code was only for the case when the user enters the text character by character. I've edited my answer. – user Mar 18 '12 at 15:57
  • Your first code is what I need but if I go to the middle of the text the space appears, so it only works if the cursor is at the end of the text. – Jani Bela Mar 18 '12 at 16:07
  • Second code is not working for me. If I press space it appears. – Jani Bela Mar 18 '12 at 16:17
  • @JaniBela Sorry about that I forgot that case. I've updated my answer with a simpler solution that should work no matter what. – user Mar 18 '12 at 16:47
  • Simple is always best;-) Nice solution! – Robert Mar 26 '14 at 17:48
  • 1
    @zeeks Add a TextWatcher(which requires you to implement 3 methods) to your EditText's and then add the code from my answer in the afterTextChanged() method of the TextWatcher. In the question you can see how to add the watcher. – user Jan 16 '16 at 14:40
  • This method is surely not working for me, phone got hanged. keyboard was showing there for infinitely even if i closed that app. Need to restart my phone! it's actually getting recursive in my view – Jimit Patel Jul 01 '16 at 10:14
  • @JimitPatel I doubt that simply using the code I posted (with nothing else added) could exhibit the behavior you mention. Please post a new question with your current code, before that try debugging the app and watch what you get as text in the TextWatcher. – user Jul 01 '16 at 11:35
  • @Luksprog, I am using your piece of code in conjuction of RXjava – Jimit Patel Jul 01 '16 at 11:36
  • @JimitPatel You should definitely post a new question(along with the RxJava code you use) as your problem is out of scope here. – user Jul 01 '16 at 11:40
  • @Luksprog, probably you are right which hold me from down voting to your answers :D. Nonetheless, I wrote down in comment because if someone failed while using it in future they will understand and probably will stop them from down voting – Jimit Patel Jul 01 '16 at 11:43
3

setSelection is there to set the cursor again at the end of your EditText:

editText.addTextChangedListener(new TextWatcher() {

                @Override
                public void onTextChanged(CharSequence cs, int arg1, int arg2,
                        int arg3) {}
                @Override
                public void beforeTextChanged(CharSequence s, int arg1, int arg2,
                        int arg3) {}
                @Override
                public void afterTextChanged(Editable arg0) {
                    if(editText.getText().toString().contains(" ")){ editText.setText(editText.getText().toString().replaceAll(" " , ""));
                    editText.setSelection(editText.getText().length());

                    Toast.makeText(getApplicationContext(), "No Spaces Allowed", Toast.LENGTH_LONG).show();
                    }
                }});
ORY
  • 393
  • 1
  • 4
  • 11
2
boolean editclicked =false ;

edittext.addTextChangedListener(new TextWatcher() {
    public void afterTextChanged(Editable s) {
        editclicked = false ;
    }

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

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        editclicked = true;
    }); 

Put this as a separate function:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (editclicked) {
        if (keyCode == KeyEvent.KEYCODE_SPACE) {
            return false
        }
    } else {
        super.onKeyDown(keyCode, event);
    }
}
Sergey Glotov
  • 20,200
  • 11
  • 84
  • 98
1
@Override
public void afterTextChanged(Editable s) {
    String result = s.toString().replaceAll("\\s", "");
    if (!s.toString().equals(result)) {
        int pos = editText.getSelectionStart() - (s.length() - result.length());
        editText.setText(result);
        editText.setSelection(Math.max(0,Math.min(pos, result.length())));
        editText.setError("No spaces allowed");
    }
}

\s matches any whitespace character (equal to [\r\n\t\f\v ])

Setting selection like this, allow you to enter or paste text in middle of edittext without loosing cursor position

John
  • 1,447
  • 15
  • 16
1

My relatively simple solution for instant whitespace deletion without removing spannables (styles) in EditText:

  1. Remove at start:

        @Override
    public void afterTextChanged(Editable s) {
        int i;
        for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
        s.replace(0, i, "");
    }
    

Basically that's it, but you can also do:

  1. Remove at start (without interrupting first input):

        @Override
    public void afterTextChanged(Editable s) {
        String text = s.toString();
        if(!text.trim().isEmpty()){
            int i;
            for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
            s.replace(0, i, "");
        }
    }
    

  1. Removing at start and end (allow 1 whitespace at end for convinient input):

        @Override
    public void afterTextChanged(Editable s) {
        int i;
        //remove at start
        for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
        s.replace(0, i, "");
        //remove at end, but allow one whitespace character
        for (i = s.length(); i > 1 && Character.isWhitespace(s.charAt(i-1)) && Character.isWhitespace(s.charAt(i-2)); i--) { ; }
        s.replace(i, s.length(), "");
    }
    
JacksOnF1re
  • 3,336
  • 24
  • 55
0

For removing the space instantly you can achieve it by two ways.

One simple solution you can set the digits to your edit text.

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 

second way you can set a filter

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


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.isSpaceChar(source.charAt(i))) {
    return "";
   }
  }
  return null;


      }
     }
King of Masses
  • 18,405
  • 4
  • 60
  • 77
  • Note that returning null here is the correct thing to do if you want to keep the text as is, despite being the most confusing thing ever. I can't wait to learn Kotlin... – technoplato Jul 05 '17 at 13:59
0

One more simple way to achieve this using the input Filter

editText.setFilters(new InputFilter[]{new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (source.toString().equalsIgnoreCase(" ")){
                return "";
            }
            return source;
        }
    }});

This will remove the space entered by the user immediately and gives appearance like space is disabled.

PranavKAndro
  • 921
  • 7
  • 9