4

Я обновил версию поддержки lib до 24.2.0, и мой экран регистрации уже мертв. Проблема находится в TextInputLayout, у меня есть два метода:TextInputLayout setError метод бросает ClassCastException в 24.2.0

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 

Я интересно, если есть какие-то новые руководства по этому поводу?

ответ

2

Исследование проблемы показало, что существует дополнительная раскладка по какой-то причине, так что теперь у нас есть 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> 
+1

Интересно, почему так просто, как это требует обходного пути? – Shaishav

+0

@Shaishav Я думал, что это своего рода анти-шаблон - они всегда говорили, что иерархия должна быть ровной, и это добавляет два дополнительных уровня, в самом начале EditText отвечал за это - только один вид. –

+0

Я не думаю, что это может быть хорошим решением. Команда библиотек поддержки Android может каждый раз изменять его, а также вы перемещаетесь в иерархии представлений с циклом и проверяете каждое представление, если оно является экземпляром. Просто используйте параметр InputTextLayout как параметр. –

1

У меня была такая же проблема с этим, и я закончил использовать эту библиотеку ->MaterialEditTest, которая была гораздо более надежной и предлагает больше возможностей.

С, что один, вам не нужно вкладывать элементы, и вы можете изменить цвет небольшой этикетки и сообщение об ошибке ...

+0

Я не рассматриваю это как решение проблемы, но кажется, что я закончу с lib, Design Lib devs передумает слишком быстро :) upvoted! –

+0

Но вы можете добавить библиотеку локально, чтобы избежать дальнейших изменений. Или просто укажите версию библиотеки, которую вы хотите использовать как * static * – Jaythaking

0

Вы можете проверить код 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); 
    } 
} 

где mInputFrame является FrameLayout.

Это причина вашей проблемы (родитель является FrameLayout).

java.lang.ClassCastException: android.widget.FrameLayout не может быть приведен к android.support.design.widget.TextInputLayout

Вы должны использовать TextInputLayout в качестве параметра вместо навигации по иерархии представлений ,

+0

Вероятно, вы не прочитали вопрос, потому что вы не поняли проблему. Конечно, вы можете найти TextInputLayout по id и установить там ошибку, но дело в том, что у вас есть EditText, и вам нужно установить Error. –

+0

@ViktorYakunin Вам не нужен EditText, чтобы установить ошибку. Вам нужно только InputTexLayout. Вы используете редакторский текст для получения родительского представления. Просто используйте метод protected void clearError (@NonNull InputTextLayout) {....} –

+0

Возможно, мой английский плохой, у меня нет идентификатора TextInputLayout, только ссылка EditText. Если вы пройдете через код, вы обнаружите, что я уже использую методы TextInputLayout. –

Смежные вопросы