Как получить параметр EditText maxLength в коде
Я хочу, чтобы во время выполнения maxLength
EditText
можно было принять решение для отображения текста.
Возможно ли это?
Вот описание того, что я не буду делать.
У меня есть ListView со многими строками, и каждая строка имеет EditText и TextView.
Я создал подкласс ArrayAdapter, чтобы иметь возможность кормить строку, которую я хочу разместить в EditText каждой строки.
Я установил android:maxLength="12"
в файле XML.
Я хочу отобразить число в этом поле EditText, но если число, которое я хочу отобразить, имеет более чем android:maxLength="12"
, вместо этого я хочу отобразить "сообщение об ошибке".
И я бы предпочел не жестко кодировать это 12 в моем подклассе ArrayAdapter.
Возможно, это простое решение, но я еще не нашел его.
(андроид первый раз...)
Ответы
Ответ 1
Только ограниченные параметры имеют свои геттеры, поэтому я не думаю, что вы можете прочитать его.
Так напишите длину (скажите 12) в папке значений и используйте ее в макете xml и arrayAdapter.
Теперь он не жестко закодирован.
1) Создайте integer.xml в значениях *
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="integer" name="max_length">12</item>
</resources>
2) В макете
<TextView android:id="@+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLength="@integer/max_length"
/>
3) в ArrayAdapter:
int maxLength = getResources().getInteger(R.integer.max_length);
Ответ 2
Это должно работать:
editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(12) });
Ответ 3
Из api 21 вы можете сделать это следующим образом:
for (InputFilter filter : mEditText.getFilters()) {
if (filter instanceof InputFilter.LengthFilter) {
((InputFilter.LengthFilter) filter).getMax());
}
}
Я надеюсь, что это поможет кому-то.
Ответ 4
расширьте текст редактирования и извлеките значение из набора атрибутов в конструкторе.
Открытый класс MyEditText расширяет EditText {
public static final String XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android";
private int mMaxLength;
public MyEditText(Context context) {
super(context, null);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mMaxLength = attrs.getAttributeIntValue(XML_NAMESPACE_ANDROID, "maxLength", -1);
}
Ответ 5
Вы можете получить значение поля с помощью API Reflection.
Почему вы не должны этого делать
Почти каждый будет защищать его (включая меня), потому что:
- Он медленный
- Он зависит от реализации
- Он не предназначен для доступа (очевидно)
На данный момент, глядя на исходный код (API API 19), реализация зависит от
InputFilter.LengthFilter
, который устанавливается в конструкторе как:
if (maxlength >= 0) {
setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) });
} else {
setFilters(NO_FILTERS);
}
где maxLength
- целое число, которое вас интересует, анализируется из атрибута xml (android:maxLength="@integer/max_length"
).
Этот InputFilter.LengthFilter
имеет только одно поле (private int mMax
) и не имеет метода доступа.
Как это можно сделать
- Объявить статический метод в соответствующем классе утилиты, который принимает
TextView
и возвращает int
.
- Итерации над каждым
InputFilter
, установленным на TextView
, и найдите тот, который принадлежит реализации InputFilter.LengthFilter
.
- Доступ, получение и возврат значения поля mMax с помощью Reflection.
Это даст вам что-то вроде этого:
import java.lang.reflect.Field;
// [...]
public static int getMaxLengthForTextView(TextView textView)
{
int maxLength = -1;
for (InputFilter filter : textView.getFilters()) {
if (filter instanceof InputFilter.LengthFilter) {
try {
Field maxLengthField = filter.getClass().getDeclaredField("mMax");
maxLengthField.setAccessible(true);
if (maxLengthField.isAccessible()) {
maxLength = maxLengthField.getInt(filter);
}
} catch (IllegalAccessException e) {
Log.w(filter.getClass().getName(), e);
} catch (IllegalArgumentException e) {
Log.w(filter.getClass().getName(), e);
} catch (NoSuchFieldException e) {
Log.w(filter.getClass().getName(), e);
} // if an Exception is thrown, Log it and return -1
}
}
return maxLength;
}
Как упоминалось ранее, это будет нарушено, если изменится реализация, устанавливающая максимальную длину TextView
. Вы получите уведомление об этом изменении при запуске метода. Даже тогда метод все равно возвращает -1, который вы должны обрабатывать как неограниченную длину.
Ответ 6
Вид сложный, но я не знаю другого подхода. Я надеюсь, что он работает (не проверен):
XmlResourceParser parser = getResources().getLayout(R.layout.theLayout);
String namespace = "http://schemas.android.com/apk/res/android";
int maxLength = parser.getAttributeIntValue(namespace, "maxLength", 12);
Ответ 7
Однолинейное решение Kotlin - возвращает максимальную длину или ноль, если не установлено
view.filters.filterIsInstance<InputFilter.LengthFilter>().firstOrNull()?.max
Как расширение:
val TextView.maxLength: Int?
get() = filters.filterIsInstance<InputFilter.LengthFilter>().firstOrNull()?.max