How to Get EditText maxLength setting in code

对着背影说爱祢 提交于 2019-12-17 10:58:14

问题


I would like to see the maxLength of an EditText at run time to be able to make a text display decision.
Is that possible?

Here is a description of what I wan't to do.

I have a ListView with many rows and each row have an EditText and a TextView.
I've made a subclass of ArrayAdapter to be able to feed the String that I want to place in the EditText of each row.
I have set android:maxLength="12" in the XML file.
I want to display a number in that EditText field, but if the number I want to display has more than android:maxLength="12" I want to display an "error message" instead.

And I would prefer not to hard code that 12 in my subclass of ArrayAdapter.

There is probably a simple solution, but I haven't found it yet.
(android first time...)


回答1:


Only limited parameters have their getters, so I don't think you can read it .

So write length (Say 12) in values folder and use it in xml layout and arrayAdapter . Now its not hard-coded .

1)Create integer.xml in values *

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="integer" name="max_length">12</item>
</resources>

2)In layout

<TextView  android:id="@+id/tv"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:maxLength="@integer/max_length"
    />

3) in ArrayAdapter :

int maxLength = getResources().getInteger(R.integer.max_length);



回答2:


This should work:

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



回答3:


From api 21 you can do it like that:

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

I hope this helps someone.




回答4:


extend the edit text and retrieve the value from the attributeset in the constructor.

public class MyEditText extends 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:


You can get the Field value using the Reflection API.

Why You Shouldn't Do It


Just about everyone would advocate against it (including me) because:

  • It's slow
  • It's implementation-dependant
  • It's not intended to be accessed (obviously)

As of now, looking at the source code (Android API 19), the implementation depends on an InputFilter.LengthFilter which is set in the constructor as:

if (maxlength >= 0) {
    setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) });
} else {
    setFilters(NO_FILTERS);
}

where maxLength is the Integer you're interested in finding, parsed from the xml attribute (android:maxLength="@integer/max_length"). This InputFilter.LengthFilter has only one field (private int mMax) and no accessor method.

How It Can Be Done


  • Declare a static method in a relevant utility class accepting a TextView and returning an int.
  • Iterate over each InputFilter set on the TextView and find one belonging to the InputFilter.LengthFilter implementation.
  • Access, get and return the mMax field's value using Reflection.

This would give you something like this:

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;
}

As mentioned earlier, this will break if the implementation that sets the maximum length of the TextView changes. You will be notified of this change when the method starts throwing. Even then, the method still returns -1, which you should be handling as unlimited length.




回答6:


Kind of complicated, but I don't know of any other approach. I hope it works (not tested):

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 one line solution - returns max length or null if not set

view.filters.filterIsInstance<InputFilter.LengthFilter>().firstOrNull()?.max

As extension:

val TextView.maxLength: Int?
    get() = filters.filterIsInstance<InputFilter.LengthFilter>().firstOrNull()?.max


来源:https://stackoverflow.com/questions/8069015/how-to-get-edittext-maxlength-setting-in-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!