Was ist der beste Weg, um die Textlänge eines EditText
in Android zu begrenzen ?
Gibt es eine Möglichkeit, dies über XML zu tun?
Was ist der beste Weg, um die Textlänge eines EditText
in Android zu begrenzen ?
Gibt es eine Möglichkeit, dies über XML zu tun?
Antworten:
maxLength
Anwesen funktioniert noch.
android:maxLength
entspricht. InputFilter.LengthFilter
Wenn Sie also den Filter programmgesteuert ändern, haben Sie auch den XML-Filter geändert.
setFilters
nicht mehr android:maxLength
funktioniert, da der vom XML-Code festgelegte Filter überschrieben wird. Mit anderen Worten, wenn Sie Filter programmgesteuert festlegen, müssen Sie sie alle programmgesteuert festlegen.
Verwenden Sie einen Eingabefilter, um die maximale Länge einer Textansicht zu begrenzen.
TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);
InputFilter
. Es wird android:maxlength
in der XML-Datei überschrieben , daher müssen wir LengthFilter
diesen Weg hinzufügen .
EditText editText = new EditText(this);
int maxLength = 3;
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
TextWatcher
.
Ein Hinweis für Personen, die bereits einen benutzerdefinierten Eingabefilter verwenden und auch die maximale Länge begrenzen möchten:
Wenn Sie Eingabefilter im Code zuweisen, werden alle zuvor eingestellten Eingabefilter gelöscht, einschließlich eines Satzes mit android:maxLength
. Ich habe dies herausgefunden, als ich versucht habe, einen benutzerdefinierten Eingabefilter zu verwenden, um die Verwendung einiger Zeichen zu verhindern, die wir in einem Kennwortfeld nicht zulassen. Nach dem Setzen dieses Filters mit setFilters wurde die maxLength nicht mehr beobachtet. Die Lösung bestand darin, maxLength und meinen benutzerdefinierten Filter programmgesteuert zusammenzusetzen. Etwas wie das:
myEditText.setFilters(new InputFilter[] {
new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});
Ich hatte dieses Problem und ich denke, wir vermissen eine gut erklärte Methode, dies programmgesteuert zu tun, ohne die bereits eingestellten Filter zu verlieren.
Festlegen der Länge in XML:
Wie in der akzeptierten Antwort korrekt angegeben, definieren Sie in Ihrem EditText-XML Folgendes, wenn Sie eine feste Länge für einen EditText definieren möchten, die Sie in Zukunft nicht weiter ändern werden:
android:maxLength="10"
Länge programmgesteuert einstellen
Um die Länge programmgesteuert einzustellen, müssen Sie sie über ein einstellen InputFilter
. Wenn Sie jedoch einen neuen InputFilter erstellen und auf setzen, EditText
gehen alle anderen bereits definierten Filter (z. B. maxLines, inputType usw.) verloren, die Sie möglicherweise entweder über XML oder programmgesteuert hinzugefügt haben.
Das ist also FALSCH :
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
Um zu vermeiden, dass zuvor hinzugefügte Filter verloren gehen, müssen Sie diese Filter abrufen, den neuen hinzufügen (in diesem Fall maxLength) und die Filter EditText
wie folgt zurücksetzen :
Java
InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(maxLength);
editText.setFilters(newFilters);
Kotlin hat es jedoch für alle einfacher gemacht. Sie müssen den Filter auch zu den bereits vorhandenen hinzufügen, aber Sie können dies mit einem einfachen:
editText.filters += InputFilter.LengthFilter(maxLength)
Für alle anderen, die sich fragen, wie sie dies erreichen können, ist hier meine erweiterte EditText
Klasse EditTextNumeric
.
.setMaxLength(int)
- Legt die maximale Anzahl von Ziffern fest
.setMaxValue(int)
- Maximaler ganzzahliger Wert begrenzen
.setMin(int)
- minimalen ganzzahligen Wert begrenzen
.getValue()
- Ganzzahligen Wert abrufen
import android.content.Context;
import android.text.InputFilter;
import android.text.InputType;
import android.widget.EditText;
public class EditTextNumeric extends EditText {
protected int max_value = Integer.MAX_VALUE;
protected int min_value = Integer.MIN_VALUE;
// constructor
public EditTextNumeric(Context context) {
super(context);
this.setInputType(InputType.TYPE_CLASS_NUMBER);
}
// checks whether the limits are set and corrects them if not within limits
@Override
protected void onTextChanged(CharSequence text, int start, int before, int after) {
if (max_value != Integer.MAX_VALUE) {
try {
if (Integer.parseInt(this.getText().toString()) > max_value) {
// change value and keep cursor position
int selection = this.getSelectionStart();
this.setText(String.valueOf(max_value));
if (selection >= this.getText().toString().length()) {
selection = this.getText().toString().length();
}
this.setSelection(selection);
}
} catch (NumberFormatException exception) {
super.onTextChanged(text, start, before, after);
}
}
if (min_value != Integer.MIN_VALUE) {
try {
if (Integer.parseInt(this.getText().toString()) < min_value) {
// change value and keep cursor position
int selection = this.getSelectionStart();
this.setText(String.valueOf(min_value));
if (selection >= this.getText().toString().length()) {
selection = this.getText().toString().length();
}
this.setSelection(selection);
}
} catch (NumberFormatException exception) {
super.onTextChanged(text, start, before, after);
}
}
super.onTextChanged(text, start, before, after);
}
// set the max number of digits the user can enter
public void setMaxLength(int length) {
InputFilter[] FilterArray = new InputFilter[1];
FilterArray[0] = new InputFilter.LengthFilter(length);
this.setFilters(FilterArray);
}
// set the maximum integer value the user can enter.
// if exeeded, input value will become equal to the set limit
public void setMaxValue(int value) {
max_value = value;
}
// set the minimum integer value the user can enter.
// if entered value is inferior, input value will become equal to the set limit
public void setMinValue(int value) {
min_value = value;
}
// returns integer value or 0 if errorous value
public int getValue() {
try {
return Integer.parseInt(this.getText().toString());
} catch (NumberFormatException exception) {
return 0;
}
}
}
Anwendungsbeispiel:
final EditTextNumeric input = new EditTextNumeric(this);
input.setMaxLength(5);
input.setMaxValue(total_pages);
input.setMinValue(1);
Alle anderen Methoden und Attribute, die für gelten EditText
, funktionieren natürlich auch.
Aufgrund der Beobachtung von goto10 habe ich den folgenden Code zusammengestellt, um zu verhindern, dass andere Filter durch Einstellen der maximalen Länge verloren gehen:
/**
* This sets the maximum length in characters of an EditText view. Since the
* max length must be done with a filter, this method gets the current
* filters. If there is already a length filter in the view, it will replace
* it, otherwise, it will add the max length filter preserving the other
*
* @param view
* @param length
*/
public static void setMaxLength(EditText view, int length) {
InputFilter curFilters[];
InputFilter.LengthFilter lengthFilter;
int idx;
lengthFilter = new InputFilter.LengthFilter(length);
curFilters = view.getFilters();
if (curFilters != null) {
for (idx = 0; idx < curFilters.length; idx++) {
if (curFilters[idx] instanceof InputFilter.LengthFilter) {
curFilters[idx] = lengthFilter;
return;
}
}
// since the length filter was not part of the list, but
// there are filters, then add the length filter
InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
newFilters[curFilters.length] = lengthFilter;
view.setFilters(newFilters);
} else {
view.setFilters(new InputFilter[] { lengthFilter });
}
}
//Set Length filter. Restricting to 10 characters only
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)});
//Allowing only upper case characters
editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()});
//Attaching multiple filters
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH), new InputFilter.AllCaps()});
Xml
android:maxLength="10"
Java:
InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(maxLength);
editText.setFilters(newFilters);
Kotlin:
editText.filters += InputFilter.LengthFilter(maxLength)
Eine andere Möglichkeit, dies zu erreichen, besteht darin, der XML-Datei die folgende Definition hinzuzufügen:
<EditText
android:id="@+id/input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="6"
android:hint="@string/hint_gov"
android:layout_weight="1"/>
Dadurch wird die maximale Länge des EditText
Widgets auf 6 Zeichen begrenzt.
Von material.io , können Sie TextInputEditText
mit kombiniert TextInputLayout
:
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="1000"
app:passwordToggleEnabled="false">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_text"
android:hint="@string/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="1000"
android:gravity="top|start"
android:inputType="textMultiLine|textNoSuggestions"/>
</com.google.android.material.textfield.TextInputLayout>
Sie können ein Passwort EditText mit drawable konfigurieren:
Oder Sie können die Textlänge mit / ohne Zähler begrenzen:
Abhängigkeit:
implementation 'com.google.android.material:material:1.1.0-alpha02'
XML
android:maxLength="10"
Programmatisch:
int maxLength = 10;
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter.LengthFilter(maxLength);
yourEditText.setFilters(filters);
Hinweis: Intern analysieren EditText & TextView den Wert von android:maxLength
in XML und verwenden ihn InputFilter.LengthFilter()
zum Anwenden .
Siehe: TextView.java # L1564
Dies ist eine benutzerdefinierte EditText-Klasse, mit der der Längenfilter zusammen mit anderen Filtern verwendet werden kann. Dank der Antwort von Tim Gallagher (unten)
import android.content.Context;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.widget.EditText;
public class EditTextMultiFiltering extends EditText{
public EditTextMultiFiltering(Context context) {
super(context);
}
public EditTextMultiFiltering(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextMultiFiltering(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setMaxLength(int length) {
InputFilter curFilters[];
InputFilter.LengthFilter lengthFilter;
int idx;
lengthFilter = new InputFilter.LengthFilter(length);
curFilters = this.getFilters();
if (curFilters != null) {
for (idx = 0; idx < curFilters.length; idx++) {
if (curFilters[idx] instanceof InputFilter.LengthFilter) {
curFilters[idx] = lengthFilter;
return;
}
}
// since the length filter was not part of the list, but
// there are filters, then add the length filter
InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
newFilters[curFilters.length] = lengthFilter;
this.setFilters(newFilters);
} else {
this.setFilters(new InputFilter[] { lengthFilter });
}
}
}
es einfache Weise in XML:
android:maxLength="4"
Wenn Sie 4 Zeichen in XML-Bearbeitungstext setzen müssen, verwenden Sie diese Option
<EditText
android:id="@+id/edtUserCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="4"
android:hint="Enter user code" />
Das funktioniert gut ...
android:maxLength="10"
Dies akzeptiert nur 10
Zeichen.
Versuchen Sie dies programmgesteuert für Java :
myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
Ich hatte viele gute Lösungen gesehen, möchte aber eine meiner Meinung nach vollständigere und benutzerfreundlichere Lösung nennen, darunter:
1, Grenzlänge.
2, Wenn Sie mehr eingeben, geben Sie einen Rückruf, um Ihren Toast auszulösen.
3, Cursor kann in der Mitte oder am Ende sein.
4, Benutzer kann durch Einfügen einer Zeichenfolge eingeben.
5, Überlaufeingabe immer verwerfen und Ursprung behalten.
public class LimitTextWatcher implements TextWatcher {
public interface IF_callback{
void callback(int left);
}
public IF_callback if_callback;
EditText editText;
int maxLength;
int cursorPositionLast;
String textLast;
boolean bypass;
public LimitTextWatcher(EditText editText, int maxLength, IF_callback if_callback) {
this.editText = editText;
this.maxLength = maxLength;
this.if_callback = if_callback;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (bypass) {
bypass = false;
} else {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(s);
textLast = stringBuilder.toString();
this.cursorPositionLast = editText.getSelectionStart();
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().length() > maxLength) {
int left = maxLength - s.toString().length();
bypass = true;
s.clear();
bypass = true;
s.append(textLast);
editText.setSelection(this.cursorPositionLast);
if (if_callback != null) {
if_callback.callback(left);
}
}
}
}
edit_text.addTextChangedListener(new LimitTextWatcher(edit_text, MAX_LENGTH, new LimitTextWatcher.IF_callback() {
@Override
public void callback(int left) {
if(left <= 0) {
Toast.makeText(MainActivity.this, "input is full", Toast.LENGTH_SHORT).show();
}
}
}));
Was ich nicht getan habe, ist, wenn der Benutzer einen Teil der aktuellen Eingabe hervorhebt und versucht, eine sehr lange Zeichenfolge einzufügen, weiß ich nicht, wie die Hervorhebung wiederhergestellt werden soll.
Beispielsweise wird die maximale Länge auf 10 festgelegt, der Benutzer gibt '12345678' ein und markiert '345' als Hervorhebung. Versuchen Sie, eine Zeichenfolge von '0000' einzufügen, die die Begrenzung überschreitet.
Wenn ich versuche, edit_text.setSelection (start = 2, end = 4) zu verwenden, um den Ursprungsstatus wiederherzustellen, wird nur 2 Leerzeichen als '12 345 678 'eingefügt, nicht das Ursprungshighlight. Ich möchte, dass jemand das löst.
Kotlin:
edit_text.filters += InputFilter.LengthFilter(10)
ZTE Blade A520
hat seltsame Wirkung. Wenn Sie mehr als 10 Symbole eingeben (z. B. 15), EditText
werden die ersten 10 angezeigt, andere 5 sind jedoch nicht sichtbar und nicht zugänglich. Wenn Sie jedoch Symbole mit löschen Backspace
, werden zuerst die rechten 5 Symbole gelöscht und dann die verbleibenden 10 entfernt. Um dieses Verhalten zu überwinden, verwenden Sie eine Lösung :
android:inputType="textNoSuggestions|textVisiblePassword"
android:maxLength="10"
oder dieses:
android:inputType="textNoSuggestions"
oder dies, wenn Sie Vorschläge haben möchten:
private class EditTextWatcher(private val view: EditText) : TextWatcher {
private var position = 0
private var oldText = ""
override fun afterTextChanged(s: Editable?) = Unit
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
oldText = s?.toString() ?: ""
position = view.selectionStart
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val newText = s?.toString() ?: ""
if (newText.length > 10) {
with(view) {
setText(oldText)
position = if (start > 0 && count > 2) {
// Text paste in nonempty field.
start
} else {
if (position in 1..10 + 1) {
// Symbol paste in the beginning or middle of the field.
position - 1
} else {
if (start > 0) {
// Adding symbol to the end of the field.
start - 1
} else {
// Text paste in the empty field.
0
}
}
}
setSelection(position)
}
}
}
}
// Usage:
editTextWatcher = EditTextWatcher(view.edit_text)
view.edit_text.addTextChangedListener(editTextWatcher)
es einfache Weise in XML:
android:maxLength="@{length}"
Zum programmgesteuerten Einstellen können Sie die folgende Funktion verwenden
public static void setMaxLengthOfEditText(EditText editText, int length) {
InputFilter[] filters = editText.getFilters();
List arrayList = new ArrayList();
int i2 = 0;
if (filters != null && filters.length > 0) {
int length = filters.length;
int i3 = 0;
while (i2 < length) {
Object obj = filters[i2];
if (obj instanceof LengthFilter) {
arrayList.add(new LengthFilter(length));
i3 = 1;
} else {
arrayList.add(obj);
}
i2++;
}
i2 = i3;
}
if (i2 == 0) {
arrayList.add(new LengthFilter(length));
}
if (!arrayList.isEmpty()) {
editText.setFilters((InputFilter[]) arrayList.toArray(new InputFilter[arrayList.size()]));
}
}