14

我正在创建简单的 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;
}
4

6 回答 6

11

更新:
使用小部件TextInputEditText而不是EditText在 TextInputLayout 内。

旧答案

TextInputLayout textInputLayout = (TextInputLayout) editText.getParent().getParent();

这似乎是一种快速解决方法。远非理想。

于 2016-08-30T14:04:07.207 回答
9

getParentForAccessibility()为我工作

于 2016-12-15T06:59:59.833 回答
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)
于 2017-02-01T16:12:25.310 回答
4

仅摘自Android 官方文档

 <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 下存在的实际视图层次结构不能保证与以 XML 编写的视图层次结构相匹配。因此,对 TextInputLayout 的子项(例如 TextInputEditText)的 g​​etParent() 调用可能不会返回 TextInputLayout 本身,而是返回一个中间视图。如果您需要直接访问视图,请设置一个 android:id 并使用 findViewById(int)。

因此,要解决这个问题,您必须转向findViewById而不是getParent由于版本 24 中引入的额外布局。

于 2016-11-03T04:31:11.993 回答
2

您可以检查TextInputLayoutv24.xx的代码
现在它可以与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);
    }
}

哪里mInputFrameFrameLayout
这是您的问题的原因(父母是 a FrameLayout)。

只需传递tilParamas 参数,而不是在getParent()需要时使用它。

于 2016-08-31T20:17:11.683 回答
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 的解决方案,直到我发现对于我的特定问题,最好按照上面的方法做。

于 2019-10-09T14:38:09.743 回答