2013-08-30 9 views
13

Sto tentando di implementare uno EditText che limita l'input ai caratteri maiuscoli solo [A-Z0-9] con cifre pure.InputFilter on EditText causa testo ripetuto

Ho iniziato con il metodo InputFilter da qualche post.But qui sto ottenendo un problema sul Samsung Galaxy Tab 2, ma non in emulatore o Nexus 4.

problema è come questo:

  1. Quando Digito "A" il testo mostra come "A" è buono
  2. Ora quando digito "B" il testo deve essere "AB" ma mi dà "AAB" questo sembra molto strano.

In breve si ripete caratteri

Ecco il codice che sto lavorando con questo codice: codice del file

public class DemoFilter implements InputFilter { 

    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, 
      int dend) { 

     if (source.equals("")) { // for backspace 
      return source; 
     } 
     if (source.toString().matches("[a-zA-Z0-9 ]*")) // put your constraints 
                 // here 
     { 
      return source.toString().toUpperCase(); 
     } 
     return ""; 
    } 
} 

XML:

<EditText 
    android:id="@+id/et_licence_plate_1" 
    android:layout_width="0dp" 
    android:layout_height="wrap_content" 
    android:layout_weight="3" 
    android:hint="0" 
    android:imeOptions="actionNext" 
    android:inputType="textNoSuggestions" 
    android:maxLength="3" 
    android:singleLine="true" 
    android:textSize="18px" > 
</EditText> 

Sono totalmente bloccato fino su questo, quindi qualsiasi aiuto qui sarebbe molto apprezzato.

risposta

1

InputFilters può essere collegato a S modificabile per vincolare le modifiche che possono essere apportate a. Fare riferimento che dà risalto sulle modifiche apportate, piuttosto che tutto il testo che contiene ..

Segui come indicato di seguito ...

public class DemoFilter implements InputFilter { 

     public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, 
       int dend) { 

      if (source.equals("")) { // for backspace 
       return source; 
      } 
      if (source.toString().matches("[a-zA-Z0-9 ]*")) // put your constraints 
                  // here 
      { 
       char[] ch = new char[end - start]; 

       TextUtils.getChars(source, start, end, ch, 0); 

       // make the characters uppercase 
       String retChar = new String(ch).toUpperCase(); 
       return retChar; 
      } 
      return ""; 
     } 
    } 
+0

grazie per la risposta, mi permetta di controllare questo funziona o no? –

+0

Non funziona –

+0

Huh, ho controllato il codice postato qui, e funziona come previsto, puoi anche postare l'implementazione del file xml del tuo editText in cui stai aggiungendo questo DemoFilter .. – CRUSADER

0

provare questo:

class CustomInputFilter implements InputFilter { 
    StringBuilder sb = new StringBuilder(); 

    @Override 
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
     Log.d(TAG, "filter " + source + " " + start + " " + end + " dest " + dest + " " + dstart + " " + dend); 
     sb.setLength(0); 
     for (int i = start; i < end; i++) { 
      char c = source.charAt(i); 
      if (Character.isUpperCase(c) || Character.isDigit(c) || c == ' ') { 
       sb.append(c); 
      } else 
      if (Character.isLowerCase(c)) { 
       sb.append(Character.toUpperCase(c)); 
      } 
     } 
     return sb; 
    } 
} 

questo permette anche di filtraggio quando il filtro() metodo accetta più caratteri contemporaneamente ad es testo incollato da un blocco appunti

8

Il problema della duplicazione dei caratteri deriva dall'esecuzione errata di InputFilter. Piuttosto restituire null se la sostituzione non dovrebbe cambiare:

@Override 
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
    boolean keepOriginal = true; 
    StringBuilder sb = new StringBuilder(end - start); 
    for (int i = start; i < end; i++) { 
     char c = source.charAt(i); 
     if (isCharAllowed(c)) // put your condition here 
      sb.append(c); 
     else 
      keepOriginal = false; 
    } 
    if (keepOriginal) 
     return null; 
    else { 
     if (source instanceof Spanned) { 
      SpannableString sp = new SpannableString(sb); 
      TextUtils.copySpansFrom((Spanned) source, start, end, null, sp, 0); 
      return sp; 
     } else { 
      return sb; 
     }   
    } 
} 

private boolean isCharAllowed(char c) { 
    return Character.isUpperCase(c) || Character.isDigit(c); 
} 
+0

Questo è corretto. Vedi l'implementazione di InputFilter.AllCaps, che copia il testo del risultato come mostrato qui. –

+2

Puoi provare android: inputType = "textVisiblePassword" per disabilitare il completamento automatico che è il vero problema per il filtro di input. Non sarebbe il modo giusto, ma funziona. Saluti! –

+0

La tua soluzione funziona! È sufficiente notare che questo problema si verifica solo su Android 7, ma non su Android 6 o Android 8 (almeno per la mia app). –

1

che ho incontrato lo stesso problema, dopo aver fissato con soluzioni postato qui c'era ancora una questione in sospeso con le tastiere con completamento automatico. Una soluzione è impostare l'inputType come 'visiblePassword', ma questo è ridurre la funzionalità no?

sono stato in grado di risolvere la soluzione, al ritorno il risultato non nullo nel metodo filter(), utilizzare la chiamata

TextUtils.copySpansFrom((Spanned) source, start, newString.length(), null, newString, 0); 

Questo copia le campate completamento automatico nel nuovo risultato e fissa lo strano comportamento della ripetizione quando si selezionano i suggerimenti di completamento automatico.

+0

Grazie per questo, copiare Spans mi ha risolto, ma a volte la mia app si bloccava a causa del fatto che 'source' non era sempre' Spanned'. Quindi la mia soluzione è: 'if (source instanceof Spanned) { \t TextUtils.copySpansFrom (sorgente (con spanning), start, newString.length(), null, newString, 0); \t } return newString; ' – Robyer

2

Ho trovato molti bug nell'InputFilter di Android, non sono sicuro che questi siano bug o destinati a esserlo. Ma sicuramente non ha soddisfatto le mie esigenze.Così ho scelto di usare TextWatcher invece di InputFilter

private String newStr = ""; 

myEditText.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
      // Do nothing 
     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      String str = s.toString(); 
      if (str.isEmpty()) { 
       myEditText.append(newStr); 
       newStr = ""; 
      } else if (!str.equals(newStr)) { 
       // Replace the regex as per requirement 
       newStr = str.replaceAll("[^A-Z0-9]", ""); 
       myEditText.setText(""); 
      } 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
      // Do nothing 
     } 
    }); 

Il codice di cui sopra non consente agli utenti di digitare qualsiasi simbolo speciale nella vostra EditText. Sono ammessi solo caratteri alfanumerici maiuscoli.

0

La seguente soluzione supporta anche la possibilità di una tastiera di completamento automatico

editTextFreeNote.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) { 
      String newStr = s.toString(); 
      newStr = newStr.replaceAll("[a-zA-Z0-9 ]*", ""); 
      if(!s.toString().equals(newStr)) { 
       editTextFreeNote.setText(newStr); 
       editTextFreeNote.setSelection(editTextFreeNote.getText().length()); 
      } 
     } 

     @Override 
     public void afterTextChanged(Editable s) {} 
    }); 
Problemi correlati