Сбой 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 на устройствах?


Ответы:


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.

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

Спасибо

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.