[Android] EditText key events

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • PaulEm
  • Registratie: Januari 2008
  • Laatst online: 03-02 07:52
Sinds vandaag ben ik een begonnen met het leren van de Android SDK. Basis dingentjes lukken mij al wel, echter loop ik nu vast op het afhandelen van keyevents op een EditText.

Ik heb dus een EditText met daarop een paar InputFilters, namelijk:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        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.isLetter(source.charAt(i))) { 
                         return "";     
                     }
                }
                return null;   
            } 
        };

        EditText test = (EditText) findViewById(R.id.editText1);
        test.setFilters(new InputFilter[] {
            new InputFilter.AllCaps(),
            new InputFilter.LengthFilter(1),
            filter
        });


Dit zorgt ervoor dat het alleen maar CAPITAL letters in mogen, een lengte van 1 en alleen maar A-Z characters. Dit werkt allemaal naar behoren, maar nu wil ik dat zodra er een letter aan getikt wordt hij de EditText leeg maakt zodat er plaats gemaakt wordt voor de volgende letter.

Ik heb al enorm veel lopen zoeken en verschillende methodes geprobeerd. Extenden van de EditText en daar een onKeyDown event overriden, geen succes.
Ook heb ik geprobeerd met een TextWatcher te werken maar dit mocht ook niet baten.

Kan iemand mij uitleggen wat ik verkeerd doe en hoe ik wel een "keydown" kan toepassen op een EditText?

Acties:
  • 0 Henk 'm!

  • Foxpat
  • Registratie: April 2011
  • Laatst online: 22-09 15:38
Kun je niet de setOnKeyListener methode op je edittext aanroepen, en vervolgens een private class maken die dit afhandelt met "implements OnKeyListener"? Of misschien zelfs dezelfde class.

En dan de methode public boolean onKey (View v, int keyCode, KeyEvent event) overriden.

[ Voor 3% gewijzigd door Foxpat op 10-03-2012 15:56 ]


Acties:
  • 0 Henk 'm!

  • PaulEm
  • Registratie: Januari 2008
  • Laatst online: 03-02 07:52
Foxpat schreef op zaterdag 10 maart 2012 @ 15:55:
Kun je niet de setOnKeyListener methode op je edittext aanroepen, en vervolgens een private class maken die dit afhandelt met "implements OnKeyListener"? Of misschien zelfs dezelfde class.

En dan de methode public boolean onKey (View v, int keyCode, KeyEvent event) overriden.
Ik heb dit geprobeerd, echter werkt de OnKey methode kennelijk alleen maar op de Enter en Backspace key.

Java:
1
2
3
4
5
6
7
        final EditText test = (EditText) findViewById(R.id.editText1);
        test.setOnKeyListener(new OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                Toast.makeText(getApplicationContext(), test.getText(), Toast.LENGTH_SHORT).show();
                return true;
            }
        });

Acties:
  • 0 Henk 'm!

  • Foxpat
  • Registratie: April 2011
  • Laatst online: 22-09 15:38
Oh, je hebt gelijk. Sorry. Die OnKeyListener werkt alleen voor enter en backspace.

Hoezo werkte een textwatcher niet dan?


EDIT:
zoiets:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
editText.addTextChangedListener(new TextWatcher() {

   ...

  @Override
  public void afterTextChanged(Editable s) {
    if (s.toString().trim().length() == 0) // Tegen recursieve loops
      return;
    editText.setText("");
    s.clear();
  }
});


Niet getest, maar zou toch moeten werken?

[ Voor 58% gewijzigd door Foxpat op 10-03-2012 16:12 ]


Acties:
  • 0 Henk 'm!

  • PaulEm
  • Registratie: Januari 2008
  • Laatst online: 03-02 07:52
Foxpat schreef op zaterdag 10 maart 2012 @ 16:09:
Oh, je hebt gelijk. Sorry. Die OnKeyListener werkt alleen voor enter en backspace.

Hoezo werkte een textwatcher niet dan?
De applicatie crashed zodra ik een letter invoer in de EditText

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        final EditText test = (EditText) findViewById(R.id.editText1);
        test.addTextChangedListener(new TextWatcher() {
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                test.setText("");
            }
            
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

            }

            public void afterTextChanged(Editable arg0) {
                
            }
        });

Acties:
  • 0 Henk 'm!

  • Foxpat
  • Registratie: April 2011
  • Laatst online: 22-09 15:38
Dat komt dus waarschijnlijk omdat hij in een recursieve loop vast gaat zitten.

Hij roept beforeTextChanged aan als je iets invult, dan zet hij 'm op "" waardoor hij weer de beforeTextChanged aanroept, waardoor hij hem weer op "" zet en ga zo maar door. In het stukje code in mijn vorige post heb ik daar een check voor aangemaakt.

Acties:
  • 0 Henk 'm!

  • PaulEm
  • Registratie: Januari 2008
  • Laatst online: 03-02 07:52
Foxpat schreef op zaterdag 10 maart 2012 @ 16:15:
Dat komt dus waarschijnlijk omdat hij in een recursieve loop vast gaat zitten.

Hij roept beforeTextChanged aan als je iets invult, dan zet hij 'm op "" waardoor hij weer de beforeTextChanged aanroept, waardoor hij hem weer op "" zet en ga zo maar door. In het stukje code in mijn vorige post heb ik daar een check voor aangemaakt.
Ah, had niet gezien dat je post geupdate was. Met jouw code kan ik totaal niks in de EditText plaatsen, wanneer ik het aanpas naar:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        final EditText test = (EditText) findViewById(R.id.editText1);
        test.addTextChangedListener(new TextWatcher() {
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                if(test.getText().length() == 0) {
                    return;
                }
                
                test.setText("");
            }
            
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            }

            public void afterTextChanged(Editable s) {
            } 
        });


Resulteert dit alsnog in een crash.

Acties:
  • 0 Henk 'm!

  • Foxpat
  • Registratie: April 2011
  • Laatst online: 22-09 15:38
Heb zelf een testprojectje opgezet, dit werkte bij mij:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        final EditText test = (EditText) findViewById(R.id.editText1);
        test.addTextChangedListener(new TextWatcher() {
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                
            }
            
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            }

            public void afterTextChanged(Editable s) {
                if(test.getText().length() == 0 || test.getText().length() == 1) {
                    return;
                }
                
                if(test.getText().length() == 2){
                    test.setText(test.getText().subSequence(1, 2));
                    test.setSelection(test.getText().length());
                }
            } 
        });


Ik heb alleen geen input filters gebruikt, ik weet niet of dit conflicten gaat opleveren maar ik denk het niet.

Acties:
  • 0 Henk 'm!

  • PaulEm
  • Registratie: Januari 2008
  • Laatst online: 03-02 07:52
Foxpat schreef op zaterdag 10 maart 2012 @ 16:30:
Heb zelf een testprojectje opgezet, dit werkte bij mij:

Java:
1
       ...


Ik heb alleen geen input filters gebruikt, ik weet niet of dit conflicten gaat opleveren maar ik denk het niet.
Hij gaf een conflict met de MaxLength filter, maar die er gewoon tussen uit gehaald aangezien het stukje wat jij gaf in feite het zelfde doet ;)

Het enige probleem is dat dit niet werkt wanneer ik mijn toetsenbord via de Emulator gerbuik. Is er nog een manier om dit te simuleren dat hij het zelfde doet?

Edit:
Nevermind, dit werkt wel. Ik had hem al zo ver aangepast dat hij naar de volgende EditText focussed en daar zitten die events natuurlijk niet op gebinded.

Heel erg bedankt, werkt prima na een paar kleine aanpassingen! ;)

[ Voor 54% gewijzigd door PaulEm op 10-03-2012 16:49 ]


Acties:
  • 0 Henk 'm!

  • Stukfruit
  • Registratie: Oktober 2007
  • Niet online
Wat PurpleMadness doet is min of meer correct. Je mag alleen in afterTextChanged de tekst veranderen. In before- en onTextChanged mag je niet de tekst wijzigen. Staat ook in de documentatie, maar het wordt daar inderdaad erg onduidelijk uitgelegd.

Er zijn trouwens een paar simpele regels:

• Wil je alleen specifieke tekstinvoer hebben zoals alles in hoofdletters of juist het niet toestaan van bepaalde karakters, dan gebruik je een KeyListener. DigitsKeyListener (alleen getallen) is hier een goed voorbeeld om van af te kijken.
• Wil je de tekst ook echt wijzigen (in de vorm van het toevoegen of verwijderen van nieuwe karakters) en niet alleen bepaalde invoer tegenhouden, dan gebruik je een TextWatcher.

Voor wat jij wil hoef je trouwens niet meer dan een TextKeyListener te gebruiken met TextKeyListener.Capitalize.CHARACTERS voor het eerste argument en een TextWatcher voor het verzorgen van de beperkte lengte :)

[ Voor 8% gewijzigd door Stukfruit op 11-03-2012 07:32 ]

Dat zit wel Schnorr.

Pagina: 1