2016-08-26 3 views
10

Я создаю простой AppCompatEditText, добавляя OnFocusChangeListener и помещая его в простой TextInputLayout.AppCompatEditText.getpParent() внутри TextInputLayout возвращает FrameLayout

Когда AppCompatEditText теряет фокус, контент должен быть проверен методом isValidParam.

Это работало до вчерашнего дня, когда я использовал rev.23.0.3 Но теперь, когда я использовал rev.24.0.2, он дает ошибку, как показано ниже в 1-й строке метода 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; 
} 
+0

Я извиняюсь за мою ошибку. Ошибка произошла в rev.24.2.0, но не на rev.24.0.2 –

+0

Каков ваш XML-макет? –

ответ

3

Update:
Используйте виджет TextInputEditText вместо EditText внутри TextInputLayout.

старый ответ

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

Это, кажется, работает как быстро исправить. Далек от идеала.

+0

Много thanx @tom_brinkkemper. Даже это далеко не идеальный, но он работает. –

+0

, возможно, знак принят;) –

+0

@AkmalUmaraliev Я заметил это предупреждение в журналах: I/TextInputLayout: Добавлен EditText не TextInputEditText. Вместо этого переключитесь на использование этого класса. Это может привести к лучшему решению! –

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); 
    } 
} 

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

Просто передайте tilParam в качестве параметра, вместо использования getParent(), если вам нужно его использовать.

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 НЕ гарантированно соответствовать иерархии вида, как написано в XML. В результате вызывает getParent() для дочерних элементов TextInputLayout - например, TextInputEditText - может не возвращать сам TextInputLayout, но скорее является промежуточным представлением. Если вам нужно напрямую получить доступ к представлению, настроит android: id и используйте findViewById (int).

Поэтому, чтобы решить эту проблему, вы должны обратиться к findViewById вместо getParent из-за дополнительной раскладки между ними введены в версии 24.

7

getParentForAccessibility() работал для меня

+1

Спасибо, брат. Ваш ответ сработал для меня. TextInputLayout textInputLayout = (TextInputLayout) editText.getParentForAccessibility(); – Jigar

+0

Спасибо Vaisakh. Ваш ответ очень помог. – xrnd

+0

Кажется, грязный рубить. Почему это работает? –

2

Вы можете проверить, если 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) 
+0

Это лучший ответ, поскольку он гарантированно работает с будущими версиями Android, в отличие от 'getParent(). GetParent()'. –