TextInputLayout中的AppCompatEditText.getpParent()返回FrameLayout

时间:2016-08-26 10:39:26

标签: android android-design-library textinputlayout

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

6 个答案:

答案 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 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>
  

注意: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);
    }
}

其中mInputFrameFrameLayout 这是您出问题的原因(父母是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的解决方案,直到发现针对我的特定问题最好执行上述操作。