Сбой Android 8.0 Oreo при фокусировке TextInputEditText

101

После обновления некоторых наших устройств до Android 8.0 при фокусировке на TextInputEditTextполе внутри a TextInputLayoutприложение вылетает следующим образом Exception:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.view.View.getBoundsOnScreen(android.graphics.Rect)' on a null object reference
at android.app.assist.AssistStructure$WindowNode.(AssistStructure.java)
at android.app.assist.AssistStructure.(AssistStructure.java)
at android.app.ActivityThread.handleRequestAssistContextExtras(ActivityThread.java:3035)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1807)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Когда мы переходим в Настройки Android -> Система -> Языки и ввод -> Дополнительно -> Служба автозаполнения -> Нет , то фокусируемся на том, что TextInputEditText / TextInputLayoutбольше не вылетает.

Как мы можем предотвратить сбой, не отключая новую службу автозаполнения 8.0 на устройствах?

Jesobremonte
источник

Ответы:

187

Я тоже столкнулся с этим. Оказывается, проблема была вызвана установкой текста подсказки для EditTextвложенных внутри TextInputLayout.

Я покопался и нашел этот самородок в примечаниях к выпуску 26.0.0 Beta 2. Примечания к выпуску поддержки Android, июнь 2017 г.

TextInputLayout должен устанавливать подсказки для onProvideAutofillStructure ()

Это побудило меня попробовать установить подсказку TextInputLayoutвместо вложенного EditText.

Это решило проблему сбоя для меня. Пример:

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Some Hint Text"
    android.support.design:hintAnimationEnabled="true"
    android.support.design:hintEnabled="true"
    android.support.design:layout_marginTop="16dp">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</android.support.design.widget.TextInputLayout>

Я разместил это как ответ здесь, так как перепутал закладки. Извините за отправку одного и того же ответа дважды.

Азетот
источник
Будет ли это работать без android.support.design:hintAnimationEnabled и android.support.design:hintEnabled? Я посмотрел на источник TextInputLayout, оба атрибута, кажется, установлены по умолчанию при загрузке атрибутов.
androidguy
@androidguy да, он должен работать без этих атрибутов. Эти атрибуты сообщают TextInputLayout о выделении места в макете для этих элементов (или, по крайней мере, это то, что я наблюдал)
Азетот
@Azethoth Это решение не сохраняет поведение. В моем случае я использую его для анимации плавающих меток. Когда я использую его таким образом, подсказка / метка не появляется. Все, что я вижу, это ввод текста
KrishnaCA
@KrishnaCA, это довольно странно. Я использую этот подход повсюду в своем приложении, и он показывает подсказку в тексте редактирования и анимирует его как плавающую метку. Я не уверен, что может вызвать вашу проблему. Можете ли вы опубликовать образец кода вашего XML-макета в вопросе и связать меня с ним? Я был бы рад помочь.
Азетот
Это то же самое, что написано в вашем ответе. Устройство, которое я тестировал, это Huawei
KrishnaCA
25

Добавьте указанный ниже атрибут в свой EditText:

android:importantForAutofill="noExcludeDescendants"

Гаурав Сингх
источник
Функция предназначена только для API 26, есть ли решение, если ваш min API меньше 26?
JPM
2
@JPM Не беспокойтесь, он просто игнорируется на более старых уровнях API, поэтому он не выйдет из строя и не будет проблемой.
Пей
2
Проблема @JPM есть только в Oreo, поэтому она будет проигнорирована для старых API и не приведет к сбою для них.
Гаурав Сингх
Я его в PROD теперь на моем приложение , кажется, работает нормально
JPM
1
Это неправильное решение. Он вылетает, когда вы долгое время нажимаете на EditText и выбираете в меню Автозаполнение. Правильное (хотя и требует кода) решение: stackoverflow.com/a/46698028/1714102
Przemo
11

Люк Симпсон почти все исправил, просто следует использовать "styles.xml" вместо "themes.xml".

Я создал новый файл стиля с квалификатором версии, стремясь к v26, чтобы сделать его более понятным.
Просто скопируйте и вставьте свой AppThemeфайл v26 / styles.xml и добавьте editTextStyleэлементы EditTextStyleстиля.

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="android:editTextStyle">@style/App_EditTextStyle</item>
    <item name="editTextStyle">@style/App_EditTextStyle</item>
</style>

<style name="App_EditTextStyle" parent="@android:style/Widget.EditText">
    <item name="android:importantForAutofill">noExcludeDescendants</item>
</style>

Таким образом, вы вносите эти изменения для всех ваших EditTexts без необходимости изменять файлы макета.

Энди Сильвейра
источник
1
Обратите внимание на минимальные требования к API, которые необходимо разместить в папке ресурсов v26.
StarWind0
6

Вы можете установить любое значение для importantForAutofill со стилем или в XML, это исправление для NPE, когда вы фокусируете EditText, но это не исправлено, если вы долго нажимаете EditText и нажимаете на AutoFill. Я нашел ошибку Сообщить об этой ошибке здесь , пожалуйста , добавьте звезду и поделиться своими наблюдениями в сообщении об ошибке также.

Спасибо.

Николас Ван Дамм
источник
5

Я использовал v26 / themes.xml, чтобы переопределить автозаполнение стиля EditText только для Oreo 8.0.0:

<style name="EditTextStyle" parent="Widget.AppCompat.EditText">
    <item name="android:importantForAutofill">noExcludeDescendants</item>
</style>

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

// HAD TO DO THIS IN LAYOUT XML FOR EACH EDIT TEXT
<EditText
    style="@style/EditTextStyle"
    ... />


// THIS DIDN'T TAKE EFFECT IN THEMES XML (HAS BEEN ADDED TO MANIFEST)
<style name="APP_THEME" parent="@style/Theme.AppCompat.Light">
    <item name="android:editTextStyle">@style/EditTextStyle</item>
    <item name="editTextStyle">@style/EditTextStyle</item>
</style>
Люк Симпсон
источник
0

@ Люк Симпсон прав. Вы можете использовать его в themes.XML, например: -

<item name="editTextStyle">@style/AppEditTextStyle</item>

and then put
<style name="AppEditTextStyle" parent="Widget.AppCompat.EditText">
        <item name="android:importantForAutofill">auto</item>
 </style>

в V26 / app_styles.xml

Но мне пришлось поместить пустой тег также в app_styles.xml в папке по умолчанию. В противном случае все свойства текста редактирования переопределялись этим, и мой текст редактирования не работал должным образом. И когда вы помещаете свойство importantForAutoFill для v26 и хотите, чтобы автозаполнение работало в 8.1, вы можете просто указать

<style name="AppEditTextStyle" parent="Widget.AppCompat.EditText">
        <item name="android:importantForAutofill">auto</item>
    </style>

Итак, свойство автозаполнения работает в 8.1. Он будет отключен только для версии 8.0, так как сбой происходит в версии 8.0, и это уже было исправлено в 8.1.

Моника Сайни
источник
0

Если кто-то все еще хочет " подсказку " в " TextInputEditText ", сделайте app: hintEnabled = "false" в TextInputLayout

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:hintEnabled="false"
    app:passwordToggleEnabled="true">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="password"
        android:inputType="textPassword" />

</com.google.android.material.textfield.TextInputLayout>
Пракаш Бала
источник
0

Я тоже столкнулся с этой проблемой, и, наконец, мы выяснили причину сбоя на Android 8.0 и Android 8.1.

первая причина (важная подсказка): пустая подсказка (android: hint = "") в xml приводит к сбою в устройстве oreo. Удалите эту пустую подсказку в editText при поиске по всему проекту.

Вторая причина (такая же, как объяснение выше): убедитесь, что ваша подсказка editText должна отображаться внутри TextInputLayout, если вы использовали TextInputLayout, иначе вы можете использовать подсказку внутри editText.

Надеюсь, это поможет вам !!

Спасибо

ЧАНДАН КУМАР
источник