Apa cara terbaik untuk membatasi panjang teks EditText
di Android?
Apakah ada cara untuk melakukan ini melalui xml?
Apa cara terbaik untuk membatasi panjang teks EditText
di Android?
Apakah ada cara untuk melakukan ini melalui xml?
Jawaban:
maxLength
properti masih bekerja.
android:maxLength
itu setara dengan InputFilter.LengthFilter
, jadi ketika secara terprogram mengubah filternya, Anda juga telah memodifikasi filter XML-nya.
setFilters
akan berhenti android:maxLength
berfungsi, karena menimpa filter yang ditetapkan oleh XML. Dengan kata lain, jika Anda mengatur filter apa pun secara terprogram, Anda harus mengatur semuanya secara terprogram.
gunakan filter input untuk membatasi panjang maksimal tampilan teks.
TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);
InputFilter
. Itu menimpa android:maxlength
dalam file xml, jadi kita perlu menambahkan LengthFilter
cara ini.
EditText editText = new EditText(this);
int maxLength = 3;
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
TextWatcher
.
Catatan untuk orang-orang yang sudah menggunakan filter input khusus dan juga ingin membatasi panjang maks:
Saat Anda menetapkan filter input dalam kode, semua filter input yang ditetapkan sebelumnya dihapus, termasuk satu filter dengan android:maxLength
. Saya menemukan ini ketika mencoba menggunakan filter input khusus untuk mencegah penggunaan beberapa karakter yang tidak kami izinkan dalam bidang kata sandi. Setelah mengatur filter dengan setFilters, maxLength tidak lagi diamati. Solusinya adalah mengatur maxLength dan filter kustom saya secara terprogram. Sesuatu seperti ini:
myEditText.setFilters(new InputFilter[] {
new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});
Saya telah mengalami masalah ini dan saya menganggap kita kehilangan cara yang dijelaskan dengan baik untuk melakukan ini secara terprogram tanpa kehilangan filter yang telah ditetapkan.
Mengatur panjang dalam XML:
Seperti yang dinyatakan oleh jawaban yang diterima dengan benar, jika Anda ingin menentukan panjang yang tetap ke EditText yang tidak akan Anda ubah lebih lanjut di masa mendatang, cukup tentukan di EditText XML Anda:
android:maxLength="10"
Mengatur panjang secara terprogram
Untuk mengatur panjang secara pemrograman Anda harus mengaturnya melalui InputFilter
. Tetapi jika Anda membuat InputFilter baru dan mengaturnya keEditText
Anda akan kehilangan semua filter lain yang sudah didefinisikan (misalnya maxLines, inputType, dll) yang mungkin Anda tambahkan baik melalui XML atau secara terprogram.
Jadi ini SALAH :
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
Untuk menghindari kehilangan filter yang ditambahkan sebelumnya, Anda perlu mendapatkan filter tersebut, tambahkan yang baru (maxLength dalam hal ini), dan atur kembali filter ke EditText
sebagai berikut:
Jawa
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);
Namun Kotlin membuatnya lebih mudah untuk semua orang, Anda juga perlu menambahkan filter ke yang sudah ada tetapi Anda dapat mencapainya dengan sederhana:
editText.filters += InputFilter.LengthFilter(maxLength)
Untuk orang lain yang bertanya-tanya bagaimana mencapai ini, inilah EditText
kelas saya yang diperluas EditTextNumeric
.
.setMaxLength(int)
- mengatur jumlah digit maksimum
.setMaxValue(int)
- membatasi nilai integer maksimum
.setMin(int)
- membatasi nilai integer minimum
.getValue()
- dapatkan nilai integer
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;
}
}
}
Contoh penggunaan:
final EditTextNumeric input = new EditTextNumeric(this);
input.setMaxLength(5);
input.setMaxValue(total_pages);
input.setMinValue(1);
Semua metode dan atribut lain yang berlaku EditText
, tentu saja berfungsi juga.
Karena pengamatan goto10, saya mengumpulkan kode berikut untuk melindungi dari kehilangan filter lain dengan mengatur panjang maks:
/**
* 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"
Jawa:
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)
Cara lain untuk mencapai ini adalah dengan menambahkan definisi berikut ke file XML:
<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"/>
Ini akan membatasi panjang maksimal EditText
widget hingga 6 karakter.
Dari material.io , Anda dapat menggunakan TextInputEditText
dikombinasikan dengan 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>
Anda dapat mengonfigurasi EditText kata sandi dengan drawable:
Atau Anda dapat membatasi panjang teks dengan / tanpa penghitung:
Ketergantungan:
implementation 'com.google.android.material:material:1.1.0-alpha02'
XML
android:maxLength="10"
Secara terprogram:
int maxLength = 10;
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter.LengthFilter(maxLength);
yourEditText.setFilters(filters);
Catatan: secara internal, EditText & TextView mem-parsing nilai android:maxLength
dalam XML dan gunakan InputFilter.LengthFilter()
untuk menerapkannya.
Lihat: TextView.java # L1564
Ini adalah kelas EditText kustom yang memungkinkan filter Panjang untuk hidup bersama dengan filter lainnya. Terima kasih atas Jawaban Tim Gallagher (di bawah)
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 });
}
}
}
cara sederhana di xml:
android:maxLength="4"
jika Anda perlu mengatur 4 karakter dalam xml edit-text, gunakan ini
<EditText
android:id="@+id/edtUserCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="4"
android:hint="Enter user code" />
Ini berfungsi dengan baik ...
android:maxLength="10"
ini hanya akan menerima 10
karakter.
Coba ini untuk Java secara terprogram :
myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
Saya telah melihat banyak solusi bagus, tetapi saya ingin memberikan apa yang saya pikir sebagai solusi yang lebih lengkap dan ramah pengguna, yang meliputi:
1, Batas panjang.
2, Jika masukan lebih banyak, berikan panggilan balik untuk memicu roti panggang Anda.
3, Kursor bisa di tengah atau ekor.
4, Pengguna dapat memasukkan dengan menempelkan string.
5, Selalu buang input overflow dan pertahankan asal.
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();
}
}
}));
Apa yang saya gagal lakukan adalah, jika pengguna menyorot bagian dari input saat ini dan mencoba menempelkan string yang sangat panjang, saya tidak tahu cara mengembalikan sorot.
Seperti, panjang maks diatur ke 10, pengguna memasukkan '12345678', dan tandai '345' sebagai highlight, dan mencoba menempelkan string '0000' yang akan melebihi batasan.
Ketika saya mencoba menggunakan edit_text.setSelection (start = 2, end = 4) untuk mengembalikan status asal, hasilnya adalah, ia hanya menyisipkan 2 spasi sebagai '12 345 678 ', bukan highlight asal. Saya ingin seseorang menyelesaikannya.
Kotlin:
edit_text.filters += InputFilter.LengthFilter(10)
ZTE Blade A520
memiliki efek aneh. Ketika Anda mengetik lebih dari 10 simbol (misalnya, 15), EditText
menunjukkan 10 pertama, tetapi 5 lainnya tidak terlihat dan tidak dapat diakses. Tetapi ketika Anda menghapus simbol dengan Backspace
, itu pertama menghapus kanan 5 simbol dan kemudian menghapus sisa 10. Untuk mengatasi perilaku ini gunakan solusi :
android:inputType="textNoSuggestions|textVisiblePassword"
android:maxLength="10"
atau ini:
android:inputType="textNoSuggestions"
atau ini, jika Anda ingin memiliki saran:
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)
cara sederhana di xml:
android:maxLength="@{length}"
untuk mengaturnya secara terprogram Anda dapat menggunakan fungsi berikut
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()]));
}
}