Подтвердить что ты не робот

Как получить параметр EditText maxLength в коде

Я хочу, чтобы во время выполнения maxLength EditText можно было принять решение для отображения текста.
Возможно ли это?

Вот описание того, что я не буду делать.

У меня есть ListView со многими строками, и каждая строка имеет EditText и TextView.
Я создал подкласс ArrayAdapter, чтобы иметь возможность кормить строку, которую я хочу разместить в EditText каждой строки.
Я установил android:maxLength="12" в файле XML.
Я хочу отобразить число в этом поле EditText, но если число, которое я хочу отобразить, имеет более чем android:maxLength="12", вместо этого я хочу отобразить "сообщение об ошибке".

И я бы предпочел не жестко кодировать это 12 в моем подклассе ArrayAdapter.

Возможно, это простое решение, но я еще не нашел его.
(андроид первый раз...)

4b9b3361

Ответ 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