InputFilter auf EditText - Zahlen nicht größer als 100

N

null0R

App-Anbieter (kostenpfl.)
7
Hi,

möchte sich jemand erbarmen und mir den verdammten InputFilter erklären? Ich bekomme es einfach nicht hin...

Mein Ziel: Man soll Kommazahlen eingeben, die aber zwischen 1 und 100 liegen müssen. Wenn man etwas eingibt, das aus der Reihe fällt, soll allerdings auch nicht gleich der ganze EditText-Inhalt verworfen werden, sondern einfach nicht weiter aktualisiert.

Mein Ansatz:
Code:
         InputFilter maxvalue = new InputFilter() {
             @Override
             public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                 try {
                     String input = source.toString();
                     if(Float.parseFloat(input) < 100) {
                         return null;
                     }
                     return "";
                 } catch (Exception e) {
                     return "";
                 }
             }
         };
         eage.setFilters(new InputFilter[] { maxvalue } );

Probleme mit diesem Code: Wenn man etwas nicht-vorgesehenes eingibt, löscht er gleich den ganzen Inhalt der EditText-View. Außerdem akzeptiert er keinen Punkt für Kommazahlen.

Was ich mich wirklich herzlichst frage: Wenn return ""; bewirkt, dass der gesamte Inhalt des Textfelds gelöscht wird (und nicht etwa, dass einfach keine Zeichen mehr an das Textfeld weitergeleitet werden), warum bewirkt etwa return dest.toString(); einfach nicht, dass der (alte) Inhalt des Textfelds bestehen bleibt?! Stattdessen vermehren sich die bestehenden Zeichen plötzlich explosionsartig und das Programm stürzt ab.

Bitte, bitte erklärt mir return im Zusammenhang mit einem InputFilter. :/
 
Am besten wirfst du mal den Debugger an und schaust dir an, was in den einzelnen Variablen steht.

Wenn jemand eine Zahl eintippt, dann steht in source immer nur 1 Zeichen. Nur wenn man was ins Feld reinkopiert oder du das Feld vom Programmcode aus mit einer Zahl setzt, steht in source der ganze String. Das mußt du auch jeden Fall schon mal berücksichtigen.

Dann ist natürlich noch wichtig, wieviele Zeichen schon in dest stehen, damit du weißt, an welcher Stelle der benutzer gerade seine eingabe macht.

Also ganz so einfach wie if(Float.parseFloat(input) < 100) wirds dann wohl nicht ;-)

Aber generell sollte mit return "" die Eingabe unterdrückt werden, also das eingegeben Zeichen bzw. der ganze String, falls kopiert oder zugewiesen wurde, mit return null wird die Eingabe soweit ich das noch weiß zugelassen.
 
Hi,

danke für die Antwort. :)

Am besten wirfst du mal den Debugger an und schaust dir an, was in den einzelnen Variablen steht.

Wenn jemand eine Zahl eintippt, dann steht in source immer nur 1 Zeichen. Nur wenn man was ins Feld reinkopiert oder du das Feld vom Programmcode aus mit einer Zahl setzt, steht in source der ganze String. Das mußt du auch jeden Fall schon mal berücksichtigen.
Auf die Idee bin ich auch schon gekommen, aber Log.d hat ergeben, dass in source sehr wohl der Inhalt des gesamten Textfelds steht. Zuvor versuchte ich es nämlich mit
Code:
String input = dest.toString() + source.toString();
weil ich diese Zeile in etwa so auch als Beispiel im Internet gefunden hatte. Leider erfolglos, verursachte auch Fehler.

Aber generell sollte mit return "" die Eingabe unterdrückt werden, also das eingegeben Zeichen bzw. der ganze String, falls kopiert oder zugewiesen wurde, mit return null wird die Eingabe soweit ich das noch weiß zugelassen.
Warum leert sich dann bei mir das gesamte Textfeld durch return "";? :/
 
So, Entschuldigung für den doppelten Beitrag, aber ich weiß jetzt, wodurch mein Problem verursacht ist und des Rätsels Lösung ist denkbar unbefriedigend und bietet keine Lösung für das eigentliche Problem... und zwar veralten sich schlicht und ergreifend die Tastaturen anders. Die normale (?) Android-Tastatur unter CM7 akzeptiert diese Lösung wie gewünscht:
Code:
        InputFilter maxvalue = new InputFilter() {
            @Override
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                try {
                    String input = dest.toString() + source.toString();
                    if(Float.parseFloat(input) < 100) {
                        return source;
                    }
                    return "";
                } catch (Exception e) {
                    return "";
                }
            }
        };
        eage.setFilters(new InputFilter[] { new InputFilter.LengthFilter(5), maxvalue } );
... aber SwiftKey, die Tastatur, die ich eigentlich nutze, scheint damit nichts anfangen zu können.

Außerdem finde ich, die Eingabe wirkt langsamer/verzögert und "laggt" irgendwie, wenn man so Filter anwendet.

Gibt es ansonsten irgendwelche Alternativen, um mein Problem (für alle Tastaturen) zu lösen?
Mein Ziel: Man soll Kommazahlen eingeben, die aber zwischen 1 und 100 liegen müssen. Wenn man etwas eingibt, das aus der Reihe fällt, soll allerdings auch nicht gleich der ganze EditText-Inhalt verworfen werden, sondern einfach nicht weiter aktualisiert.
Soll ichs mit einem onKeyListener probieren?

Vielen Dank. :/
 
Tja, was soll ich sagen. Dritter Beitrag in Folge und das Thema hat sich endlich erledigt. :) Irgendwie funktioniert es doch mit SwiftKey. Ich glaube, man darf entweder nicht den InputFilter abstrakt so erstellen (falls sich das so nennt), sondern sollte lieber eine eigene Klasse dafür vorziehen. Oder man darf es nicht zu Exceptions kommen lassen. Aber ehrlich gesagt weiß ich nicht, ob irgendwas damit zu tun hat.

Jedenfalls habe ich - glaube ich - nicht wirklich was anders gemacht und so funktioniert es mit beiden von mir getesteten Tastaturen:
Code:
package dein.package.name;

import android.text.InputFilter;
import android.text.Spanned;

public class InputFilterMaximumValue implements InputFilter
{
    private Integer max;
    
    
    public InputFilterMaximumValue(Integer max)
    {
        this.max = max;
    }

    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
    {
        // Möchte löschen
        if(source.length() == 0) {
            return "";
        }
        
        // Ansonsten nur normale Eingabe von Zahlen und Kommas bitte
        if(source.length() == 1 && source.toString().matches("[0-9,.]"))
        {
            // Erstes Zeichen sogar nur eine Zahl
            if(dest.length() == 0 && Character.isDigit(source.charAt(0)))
            {
                return null;
            }
            
            // Wenn noch kein Komma erhalten, dann darf das rein (deutsches wird umgewandelt)
            if(source.charAt(0) == ',' || source.charAt(0) == '.')
            {
                if(!dest.toString().contains("."))
                {
                    return ".";
                }
                return "";
            }
            
            // Eingabestring bauen
            String input = dest.subSequence(0, dstart).toString() + source.toString();
            if(dstart < dest.length())
            {
                // Cursor ist irgendwo mittendrin
                input += dest.subSequence(dstart, dest.length()).toString();
            }
            
            // Okay, letztlich gucken wir, ob das Ganze noch in die verlangte Größe passt
            if(Float.parseFloat(input) <= this.max)
            {
                return null;
            }
        }
        return "";
    }
}
Code:
        eage.setFilters(new InputFilter[] { new InputFilter.LengthFilter(5), new InputFilterMaximumValue(100) });
Funktioniert glaube ich ziemlich gut so.
 

Ähnliche Themen

Manny87
  • Manny87
Antworten
11
Aufrufe
166
swa00
swa00
R
  • raller
Antworten
15
Aufrufe
549
DOT2010
DOT2010
M
  • MikelKatzengreis
Antworten
5
Aufrufe
131
swa00
swa00
Zurück
Oben Unten