我正在创建简单的AppCompatEditText,添加OnFocusChangeListener并将其放在简单的TextInputLayout中。
当AppCompatEditText失去焦点时,它的内容应该通过isValidParam方法验证。
直到昨天,我使用rev.23.0.3 但是现在,当我使用rev.24.0.2时,它在isValidParam方法的第一行给出了如下错误。
java.lang.ClassCastException:android.widget.FrameLayout不能 强制转换为android.support.design.widget.TextInputLayout
我检查了调试模式。 AppCompatEditText.getpParent()确实返回Framelayout而不是TextInputLayout。
LinearLayout llParams = new LinearLayout(context);
llParams.setOrientation(LinearLayout.VERTICAL);
// Create label for param
final TextInputLayout tilParam = new TextInputLayout(context);
// Add label into layout
llParams.addView(tilParam);
// Create Editor for param
final AppCompatEditText etParam = new AppCompatEditText(context);
edParam.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus)
if (isValidParam(etParam)) {
do some thing;
} else {
do other thing;
}
}
});
tilParam.addView(etParam);
// validation method
boolean isValidParam(AppCompatEditText editText) {
TextInputLayout til = (TextInputLayout) editText.getParent();
String text = editText.getText().toString().trim();
if (!text.equls("some criteria") {
till.setError("Error text")
return false;
}
return true;
}
答案 0 :(得分:9)
getParentForAccessibility()
为我工作
答案 1 :(得分:6)
<强>更新强>
在TextInputLayout中使用小部件TextInputEditText
而不是EditText
。
旧回答
TextInputLayout textInputLayout = (TextInputLayout) editText.getParent().getParent();
这似乎是一个快速解决方案。远非理想。
答案 2 :(得分:5)
您可以使用以下方法检查EditText是否在TextInputLayout内:
public static <ParentClass> ParentClass getFirstParent(View view, Class<ParentClass> parentClass) {
if (view.getParent() instanceof View) {
if (parentClass.isInstance(view.getParent())) {
return (ParentClass) view.getParent();
} else {
return getFirstParent((View) view.getParent(), parentClass);
}
} else {
return null;
}
}
使用示例:
TextInputLayout textInputLayout = getFirstParent(editText, TextInputLayout.class)
答案 3 :(得分:4)
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/form_username"/>
</android.support.design.widget.TextInputLayout>
注意:TextInputLayout下的实际视图层次结构是NOT 保证匹配以XML编写的视图层次结构。结果是, 在TextInputLayout的子节点上调用getParent() - 例如 TextInputEditText - 可能不会返回TextInputLayout本身,但是 而是一个中间视图。如果您需要直接访问View, 设置一个android:id并使用findViewById(int)。
因此,要解决此问题,您必须转向findViewById
而不是getParent
,因为版本24中引入了额外的布局。
答案 4 :(得分:2)
您可以查看TextInputLayout
v24.x.x的代码。
现在它适用于FrameLayout
。
@Override
public void addView(View child, int index, final ViewGroup.LayoutParams params) {
if (child instanceof EditText) {
mInputFrame.addView(child, new FrameLayout.LayoutParams(params));
//...
} else {
// Carry on adding the View...
super.addView(child, index, params);
}
}
其中mInputFrame
是FrameLayout
这是您出问题的原因(父母是FrameLayout
)。
只需将tilParam
作为参数传递,而不是使用getParent()
,如果您需要使用它。
答案 5 :(得分:0)
TextInputLayout具有一个名为getEditText()的方法。这可能是解决问题的另一种方法。您可以从TextInputLayout开始并仅获取EditText子视图,而不是从EditText本身开始并获取父TextInputLayout。对于xml生成的视图,以下代码为示例:
TextInputLayout someInputLayout = findViewById(R.id.some_input_layout);
EditText someEditText = someInputLayout.getEditText();
String text = someEditText.getText().toString();
这可能是一个更理想的解决方案,因为它不需要任何外部方法,但是如果由于某种原因需要从EditText开始,则不能解决您的问题。我知道很久以前就已经回答了这个问题,但是我一直在使用@sylwano的解决方案,直到发现针对我的特定问题最好执行上述操作。