AppCompatEditText.getpParent() inside TextInputLayout returns FrameLayout

半世苍凉 提交于 2019-12-18 03:22:25

问题


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

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