Awaria systemu Android 8.0 Oreo podczas ustawiania ostrości TextInputEditText

101

Po zaktualizowaniu niektórych naszych urządzeń do systemu Android 8.0, po skupieniu się na TextInputEditTextpolu wewnątrz a TextInputLayout, aplikacja zawiesza się z tym 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)

Kiedy przechodzimy do Ustawienia Androida -> System -> Języki i wprowadzanie -> Zaawansowane -> Usługa autouzupełniania -> Brak , a następnie skupiając się na TextInputEditText / TextInputLayoutjuż nie ulega awarii.

Jak możemy zapobiec wystąpieniu awarii bez konieczności wyłączania nowej usługi automatycznego wypełniania 8.0 na urządzeniach?

jesobremonte
źródło

Odpowiedzi:

187

Ja też na to wpadłem. Okazuje się, że problem był spowodowany ustawieniem tekstu podpowiedzi w EditTextzagnieżdżonym pliku TextInputLayout.

Poszperałem trochę i znalazłem ten samorodek w informacjach o wydaniu 26.0.0 Beta 2. Informacje o wersji obsługi Androida, czerwiec 2017 r

TextInputLayout musi ustawić wskazówki dotyczące onProvideAutofillStructure ()

To skłoniło mnie do próby ustawienia podpowiedzi TextInputLayoutzamiast zagnieżdżenia EditText.

To rozwiązało problem z awariami. Przykład:

<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>

Opublikowałem to jako odpowiedź tutaj, gdy pomieszałem zakładki. Przepraszamy za dwukrotne opublikowanie tej samej odpowiedzi.

Azethoth
źródło
Czy to zadziała bez android.support.design:hintAnimationEnabled i android.support.design:hintEnabled? Spojrzałem na źródło TextInputLayout, oba atrybuty wydają się być ustawione jako domyślne podczas ładowania atrybutów.
androidguy
@androidguy tak, powinno działać bez tych atrybutów. Te atrybuty informują TextInputLayout, aby przydzielił miejsce w układzie dla tych elementów (a przynajmniej to zaobserwowałem)
Azethoth
@Azethoth To rozwiązanie nie zachowuje zachowania. W moim przypadku używam go do animacji pływających etykiet. Kiedy używam go w ten sposób, wskazówka / etykieta nie pojawia się. Wszystko, co widzę, to wpis tekstowy
KrishnaCA,
@KrishnaCA to dość dziwne. Używam tego podejścia wszędzie w mojej aplikacji i zarówno wyświetla wskazówkę w tekście edycji, jak i animuje ją jako pływającą etykietę. Nie wiem, co może być przyczyną Twojego problemu. Czy możesz zamieścić w pytaniu przykładowy kod swojego układu XML i połączyć mnie z nim? Chętnie pomogę.
Azethoth
To to samo, co zamieszczono w Twojej odpowiedzi. Urządzenie, dla którego testowałem to Huawei
KrishnaCA
25

Dodaj poniższy atrybut w swoim EditText:

android:importantForAutofill="noExcludeDescendants"

Gaurav Singh
źródło
Funkcja jest dostępna tylko dla interfejsu API 26. Czy istnieje rozwiązanie, jeśli minimalny interfejs API jest mniejszy niż 26?
JPM
2
@JPM Nie martw się, jest po prostu ignorowany na starszych poziomach API, więc nie ulegnie awarii ani nie będzie problemem.
Pei
2
Problem @JPM dotyczy tylko Oreo, więc zostanie zignorowany w przypadku starszych interfejsów API i nie ulegnie awarii.
Gaurav Singh
Mam to w PROD teraz w mojej aplikacji wydaje się działać dobrze
JPM
1
To jest nieprawidłowe rozwiązanie. Awaria, gdy długo naciskasz EditText i wybierasz Autouzupełnianie z menu. Prawidłowe (choć wymaga kodu) rozwiązanie: stackoverflow.com/a/46698028/1714102
Przemo
11

Luke Simpson prawie to zrobił, powinien po prostu użyć „styles.xml” zamiast „themes.xml”.

Stworzyłem nowy plik stylu z kwalifikatorem wersji, mając na celu v26, aby był bardziej przejrzysty.
Po prostu skopiuj i wklej swój AppThemedo v26 / styles.xml i dodaj editTextStyleelementy do EditTextStylestylu.

<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>

W ten sposób wprowadzasz te zmiany dla wszystkich swoich EditTextów bez konieczności zmiany plików układu.

Endy Silveira
źródło
1
Zwróci uwagę na minimalne wymaganie API, będzie musiało zostać umieszczone w folderze zasobów v26.
StarWind0
6

Możesz ustawić dowolną wartość dla importantForAutofill za pomocą stylu lub w kodzie XML, który jest poprawiony dla NPE, gdy skupisz się na EditText, ale nie zostanie to naprawione, jeśli długo naciśniesz EditText i klikniesz Autouzupełnianie. Znalazłem zgłoszenia o tego błędu tutaj , proszę dodać gwiazdkę i wymieniać się spostrzeżeniami w raporcie bug również.

Dzięki.

Nicolas Van Damme
źródło
5

Użyłem v26 / themes.xml, aby zastąpić autouzupełnianie stylu EditText tylko dla Oreo 8.0.0:

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

Zauważ, że musiałem zastosować styl w tekście dla każdego EditText w moim układzie XML, aby odniosło skutek. Próbowałem zastosować tę zmianę globalnie w motywie mojej aplikacji, ale z jakiegoś powodu nie zadziałało.

// 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>
Luke Simpson
źródło
0

@Luke Simpson ma rację. Możesz go używać w plikachmes.XML, takich jak: -

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

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

w wersji 26 / app_styles.xml

Ale musiałem umieścić pusty tag również w app_styles.xml w domyślnym folderze. W przeciwnym razie wszystkie właściwości tekstu edycji były zastępowane przez to, a mój tekst edycji nie działał poprawnie. A kiedy umieścisz właściwość importantForAutoFill dla wersji 26 i chcesz, aby autouzupełnianie działało w wersji 8.1, możesz po prostu wstawić

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

Tak więc właściwość autouzupełniania działa w wersji 8.1. Zostanie wyłączony tylko w wersji 8.0, ponieważ awaria ma miejsce w 8.0 i została już naprawiona w 8.1.

Monika Saini
źródło
0

Jeśli ktoś nadal chce „ podpowiedź ” w „ TextInputEditText ”, utwórz aplikację: hintEnabled = „false” w 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>
Prakash Bala
źródło
0

Miałem również do czynienia z tym problemem i wreszcie mamy przyczynę awarii na Androidzie 8.0 i Androidzie 8.1.

pierwszy powód (ważna wskazówka): pusta wskazówka (android: hint = "") w xml prowadzi do awarii na urządzeniu oreo. Usuń tę pustą wskazówkę z editText podczas wyszukiwania całego projektu.

Drugi powód (taki sam, jak wyjaśniono powyżej): upewnij się, że twoja wskazówka editText powinna być pokazana w TextInputLayout, jeśli użyłeś TextInputLayout, w przeciwnym razie możesz użyć wskazówki w editText.

Mam nadzieję, że to ci pomoże !!

Dziękuję Ci

CHANDAN KUMAR
źródło