【问题标题】:TextInputLayout setError method throws ClassCastException in 24.2.0TextInputLayout setError 方法在 24.2.0 中抛出 ClassCastException
【发布时间】:2016-08-25 15:55:03
【问题描述】:

我将支持库版本更新到 24.2.0,我的注册屏幕现在已经死了。问题出在TextInputLayout,我有两种方法:

    protected void setError(@Nullable CharSequence errorMsg, @NonNull EditText editText, boolean forceClean) {
        TextInputLayout viewParent = (TextInputLayout) editText.getParent();
        if (forceClean) {
            viewParent.setErrorEnabled(false);
            viewParent.setError(null);
        }
        viewParent.setErrorEnabled(true);
        viewParent.setError(errorMsg);
    }

    protected void clearError(@NonNull EditText editText) {
        TextInputLayout viewParent = (TextInputLayout) editText.getParent();
        viewParent.setErrorEnabled(false);
        viewParent.setError(null);
    }

当我尝试将 EditText 的父级转换为 TextInputLayout 时出现错误,在布局中我有这样的代码:

<android.support.design.widget.TextInputLayout
     android:layout_width="match_parent"
     android:layout_height="wrap_content">

     <android.support.design.widget.TextInputEditText
          android:id="@+id/login_registration_firstname"
          style="@style/registration_form_field"
          android:hint="@string/login_registration_firstname"
          android:inputType="textCapWords" />
</android.support.design.widget.TextInputLayout>

所以,这工作得非常好,但现在它抛出 ClassCastException:

java.lang.ClassCastException: android.widget.FrameLayout cannot be cast to android.support.design.widget.TextInputLayout

我想知道是否有一些关于这方面的新指南?

【问题讨论】:

    标签: android android-design-library android-textinputlayout


    【解决方案1】:

    问题调查表明由于某种原因存在额外的布局,所以现在我们有 TextInputLayout -> FrameLayout -> TextInputEditText ,这很可悲:( 作为临时解决方法,我创建了以下方法:

    @Nullable
    private TextInputLayout getTextInputLayout(@NonNull EditText editText) {
            View currentView = editText;
            for (int i = 0; i < 2; i++) {
                ViewParent parent = currentView.getParent();
                if (parent instanceof TextInputLayout) {
                    return (TextInputLayout) parent;
                } else {
                    currentView = (View) parent;
                }
            }
            return null;
    }
    

    这将在视图层次结构中找到您的 TextInputLayout。

    如果你很幸运,你会注意到这个粉色错误颜色变化,克服它的简单方法是在 styles.xml 中覆盖样式:

    <style name="TextAppearance.Design.Error" parent="TextAppearance.AppCompat.Caption" tools:override="true">
            <item name="android:textColor">@color/red</item>
    </style>
    

    【讨论】:

    • 我想知道,为什么这么简单的事情需要解决方法?
    • @Shaishav 我认为这是一种反模式——他们总是说层次结构应该是扁平的,而这一层增加了两个额外的层次,一开始 EditText 负责这一点——只有一个视图.
    • 我认为这不是一个好的解决方案。 Android 支持库团队可以随时更改它,并且您可以在视图层次结构中循环导航并测试每个视图是否是 instanceof。只需使用 InputTextLayout 作为参数。
    • 解决方案本身并不是最好的,但考虑到他们将在下一个版本中删除额外的 ViewGroup 并且此代码将起作用。
    【解决方案2】:

    我遇到了同样的问题,我最终使用了那个库 -> MaterialEditTest 更可靠并提供更多功能。

    有了那个,你不需要嵌套元素,你可以修改小标签颜色和错误信息......

    【讨论】:

    • 我不认为这是解决问题的方法,但似乎我最终会使用 lib,Design Lib 开发人员改变主意太快了 :) 赞成!
    • 但是您可以在本地添加库以避免对其进行任何进一步的修改。或者只是指定要使用的库版本为 static
    【解决方案3】:

    您可以查看TextInputLayout v24.2.x 的代码。
    现在它适用于FrameLayout

    public TextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        // Can't call through to super(Context, AttributeSet, int) since it doesn't exist on API 10
        super(context, attrs);
        //...
        mInputFrame = new FrameLayout(context);
        mInputFrame.setAddStatesFromChildren(true);
        addView(mInputFrame);
    
        //....
    
    }
    
    @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)。

    java.lang.ClassCastException: android.widget.FrameLayout 无法转换为 android.support.design.widget.TextInputLayout

    您应该使用TextInputLayout 作为参数,而不是在视图层次结构中导航。

    【讨论】:

    • 您可能没有阅读该问题,因为您不了解该问题。当然你可以通过id找到TextInputLayout并在那里设置错误,但重点是你有EditText,你需要设置Error。
    • @ViktorYakunin 您不需要 EditText 来设置错误。您只需要 InputTexLayout。您仅使用 editText 来获取父视图。只需使用方法 protected void clearError(@NonNull InputTextLayout) { ....}
    • 可能是我英文不好,没有TextInputLayout的id,只有EditText的引用。如果你仔细阅读代码,你会发现我已经在使用 TextInputLayout 的方法了。
    • 好的,但是只需在 InputTextLayout 中添加一个 id 以便能够调用此视图上的方法。阅读您的代码,您只需在此视图上调用 setError()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多