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

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

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

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

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

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

Solutions Collecting From Web of "Как получить параметр EditText maxLength в коде"

Только ограниченные параметры имеют свои геттеры, поэтому я не думаю, что вы можете это прочитать.

Так напишите длину (Say 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); 

Это должно работать:

 editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(12) }); 

Вы можете получить значение поля с помощью API Reflection .

Почему вы не должны этого делать


Почти каждый будет защищать его (включая меня), потому что:

  • Это медленно
  • Это зависит от реализации
  • Он не предназначен для доступа (очевидно)

На данный момент, глядя на исходный код (Android 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, который вы должны обрабатывать как неограниченную длину .

Расширьте текст редактирования и извлеките значение из набора атрибутов в конструкторе.

Открытый класс 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); } 

Из api 21 вы можете сделать это так:

 for (InputFilter filter : mEditText.getFilters()) { if (filter instanceof InputFilter.LengthFilter) { ((InputFilter.LengthFilter) filter).getMax()); } } 

Я надеюсь, что это помогает кому-то.

Сложно, но я не знаю другого подхода. Я надеюсь, что он работает (не тестировался):

 XmlResourceParser parser = getResources().getLayout(R.layout.theLayout); String namespace = "http://schemas.android.com/apk/res/android"; int maxLength = parser.getAttributeIntValue(namespace, "maxLength", 12);