问题
I am creating simple AppCompatEditText adding OnFocusChangeListener and putting it in the simple TextInputLayout.
When AppCompatEditText loosing focus it's content should be validate by isValidParam method.
It worked till yesterday, when I used rev.23.0.3 But now, when I used rev.24.0.2, it gives error as below on the 1st row of isValidParam method.
java.lang.ClassCastException: android.widget.FrameLayout cannot be cast to android.support.design.widget.TextInputLayout
I checked in debugging mode. AppCompatEditText.getpParent() really returns Framelayout instead 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;
}
回答1:
getParentForAccessibility()
worked for me
回答2:
Update:
Use the widget TextInputEditText
instead of EditText
inside a TextInputLayout.
old answer
TextInputLayout textInputLayout = (TextInputLayout) editText.getParent().getParent();
That seems to work as a quick fix. Far from ideal.
回答3:
You can check if EditText is inside TextInputLayout using following method:
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;
}
}
Example of use:
TextInputLayout textInputLayout = getFirstParent(editText, TextInputLayout.class)
回答4:
Just extracts from Android official documents:
<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>
Note: The actual view hierarchy present under TextInputLayout is NOT guaranteed to match the view hierarchy as written in XML. As a result, calls to getParent() on children of the TextInputLayout -- such as an TextInputEditText -- may not return the TextInputLayout itself, but rather an intermediate View. If you need to access a View directly, set an android:id and use findViewById(int).
Therefore, to resolve the issue you have to turn to findViewById
instead of getParent
due to an extra layout in between introduced in version 24.
回答5:
You can check the code of the TextInputLayout
v24.x.x.
Now it works with a 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);
}
}
where mInputFrame
is a FrameLayout
.
It is the reason of your issue (the parent is a FrameLayout
).
Just pass the tilParam
as parameter , instead of using getParent()
if you need to use it.
回答6:
TextInputLayout has a method called getEditText(). This may be an alternate way to solve your problem. Instead of starting from the EditText itself and getting the parent TextInputLayout, you can start with the TextInputLayout and simply get the EditText child view. For xml generated views, the following code is an example:
TextInputLayout someInputLayout = findViewById(R.id.some_input_layout);
EditText someEditText = someInputLayout.getEditText();
String text = someEditText.getText().toString();
This could possibly be a more desired solution as it does not require any external methods, though this would not solve your problem if it is required that you start from EditText for some reason. I know this has been answered a long time ago, but I was using @sylwano's solution, until I found for my particular problem it was better to do as above.
来源:https://stackoverflow.com/questions/39164321/appcompatedittext-getpparent-inside-textinputlayout-returns-framelayout