AppCompatEditText.getpParent() inside TextInputLayout returns FrameLayout
Asked Answered
J

6

14

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;
}
Jacksonjacksonville answered 26/8, 2016 at 10:39 Comment(2)
I am sorry for my mistake. Error occurred on rev.24.2.0 not on rev.24.0.2Jacksonjacksonville
What is your XML layout?Forsythe
F
11

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.

Footstep answered 30/8, 2016 at 14:4 Comment(4)
Many thanx @tom_brinkkemper. Even it is far from ideal, but it works.Jacksonjacksonville
@AkmalUmaraliev I've noticed this warning in the logs: I/TextInputLayout: EditText added is not a TextInputEditText. Please switch to using that class instead. This could lead to better solution!Footstep
@TomBrinkkemper It happens because now you should use the TextInputEditText instead of the EditText. Check stackoverflow.com/documentation/android/5652/textinputlayout/…Gemperle
Good Solution. But, It only work in 24.2.1 and later not in 24.2.0. Check out this official issue linkReynolds
R
9

getParentForAccessibility() worked for me

Revisory answered 15/12, 2016 at 6:59 Comment(3)
Thanks brother. Your answer worked for me. TextInputLayout textInputLayout = (TextInputLayout) editText.getParentForAccessibility();Rachellerachis
Thanks Vaisakh. Your answer helped a lot.Dissolvent
it worked, but now getParentForAccessibility() is suddenly returning null now.Strophic
S
5

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)
Solenoid answered 1/2, 2017 at 16:12 Comment(1)
This is the best answer as it is guaranteed to work with future versions of Android, unlike getParent().getParent().Natalia
P
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.

Polyphonic answered 3/11, 2016 at 4:31 Comment(0)
G
2

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.

Gemperle answered 31/8, 2016 at 20:17 Comment(0)
B
0

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.

Bithia answered 9/10, 2019 at 14:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.