我希望在运行时看到EditText
的maxLength
,以便能够做出文本显示决定。
这可能吗?
下面是我不想做的事情的描述。
我有一个ListView与许多行,每一行有一个EditText和一个TextView。
我已经做了一个子类的ArrayAdapter能够饲料的字符串,我想在每一行的EditText。
我在XML文件中设置了android:maxLength="12"
。
我想在EditText字段中显示一个数字,但是如果我想显示的数字超过android:maxLength="12"
,我想显示一个"错误消息"。
我不希望在我的子类ArrayAdapter中硬编码这个12
可能有一个简单的解决办法,但是我还没有找到。(android第一次…)
只有有限的参数有它们的getter,所以我认为你看不懂。
所以写长度(说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"
/>
int maxLength = getResources().getInteger(R.integer.max_length);
应该可以:
editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(12) });
在api 21中,你可以这样做:
for (InputFilter filter : mEditText.getFilters()) {
if (filter instanceof InputFilter.LengthFilter) {
((InputFilter.LengthFilter) filter).getMax());
}
}
扩展编辑文本并从构造函数的attributeset中检索值。
公共类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);
}
Kotlin一行解决方案-返回最大长度或空,如果没有设置
view.filters.filterIsInstance<InputFilter.LengthFilter>().firstOrNull()?.max
扩展:
val TextView.maxLength: Int?
get() = filters.filterIsInstance<InputFilter.LengthFilter>().firstOrNull()?.max
您可以使用反射API获取字段值。
为什么你不应该这样做
几乎每个人都会反对它(包括我),因为:
- 它缓慢的
- 的 implementation-dependant
- 不打算被访问(显然)
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
。 - 遍历
TextView
上的每个InputFilter
集合,找到一个属于InputFilter.LengthFilter
实现的集合。 - 使用反射访问,获取和返回mMax字段的值。
这将给你这样的东西:
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,您应该将其处理为无限长度。
有点复杂,但我不知道还有什么其他方法。我希望它能工作(未测试):
XmlResourceParser parser = getResources().getLayout(R.layout.theLayout);
String namespace = "http://schemas.android.com/apk/res/android";
int maxLength = parser.getAttributeIntValue(namespace, "maxLength", 12);