Ostrzeżenie „Unikaj przekazywania wartości null jako katalogu głównego widoku” podczas zwiększania widoku do użycia przez AlertDialog

126

Pojawia się ostrzeżenie, nie pozostawiającą włókien, Avoid passing null as the view rootpodczas pompowania poglądy z nulljak parent, jak:

LayoutInflater.from(context).inflate(R.layout.dialog_edit, null);

Jednak widok ma być używany jako zawartość pliku AlertDialog, używając setViewon AlertDialog.Builder, więc nie wiem, co powinno zostać przekazane jako parent.

Jak myślisz, co parentpowinno być w tym przypadku?

Randy Sugianto „Yuku”
źródło
2
Przekaż false zamiast null. zobacz to
MrDumb
Spróbuj podać układ nadrzędny zamiast null, a następnie nie używaj setView.
Haresh Chhelana
Pomijam ostrzeżenie o kłaczkach dla metody. Nie widziałem jeszcze dobrego powodu, dla którego miałbym nie zdać null.
323go
4
Rozumiem problem z układem w zależności od widoku nadrzędnego, ale tak naprawdę nie dotyczy to AlertDialog, który zasadniczo unosi się nad hierarchią widoku działania. Dlatego możesz przejść null. Jest powód, dla którego można powstrzymać kłaczki. Lint ma ostrzegać o często pomijanych problemach; w tym przypadku jest to prawidłowe wywołanie.
323go,
1
@ ashutiwari4 Codziennie uczę się nowych rzeczy .. piękny świat: I
Rahul

Odpowiedzi:

174

Użyj tego kodu, aby wypełnić okno dialogowe bez ostrzeżenia:

View.inflate(context, R.layout.dialog_edit, null);
Edward Brey
źródło
7
@ MarianPaździoch Bo to nie powoduje ostrzeżenia. :-) oczywiście, że nasuwa się pytanie, dlaczego traktuje kodowych szarpie View.inflatei LayoutInflator.inflateinaczej. Nie widziałem ostatecznej odpowiedzi. Może to być związane z tym, dlaczego istnieją dwa pozornie równoważne sposoby zawyżenia tego samego poglądu, dla którego również nie widziałem uzasadnienia.
Edward Brey
12
To jest źle. Wyłącza tylko ostrzeżenie, ale problem nadal występuje. Przeczytaj possiblemobile.com/2013/05/layout-inflation-as-intended, aby znaleźć lepsze rozwiązanie.
jcsahnwaldt Przywróć Monikę
16
@JonaChristopherSahnwaldt Czy mógłbyś to rozwinąć? Artykuł mówi, że AlertDialog powinien mieć pusty element nadrzędny, ponieważ nie ma widoku głównego. Wydaje mi się, że potwierdza to, że ostrzeżenie ma sens w przypadku widoków poza oknem dialogowym, ale nie ma zastosowania w przypadku widoku dialogowego.
Edward Brey
7
@EdwardBrey Masz rację - nie przeczytałem dokładnie tego artykułu. W tym konkretnym przypadku można użyć opcji View.inflate(...null)lub @SuppressLint. Ogólnie LayoutInflater.from(...).inflate(..., parent, false)jest lepiej. Dzięki za wskazanie tego!
jcsahnwaldt Przywróć Monikę
1
@Bevor That Avoid pass null Pytanie dotyczy przypadków, w których masz rodzica. To pytanie dotyczy tego AlertDialog, co nie zapewnia rodzica, aby widok był zawyżony. Podczas nadmuchiwania widoku roota AlertDialog, przekazywanie wartości null jest poprawne. Lint nie bierze pod uwagę tego konkretnego kontekstu, więc ostrzeżenie, które daje, jeśli używasz funkcji, która przyjmuje parentfałszywy alarm , a nie wskazuje na coś podatnego na błędy. Dlatego w tym przypadku ważne jest użycie funkcji, która nie przyjmuje odpowiedzi parenti nie wywołuje ostrzeżenia.
Edward Brey,
35

Krótko mówiąc, kiedy zawyżasz widok do okna dialogowego, parent powinna być zerowa, ponieważ nie jest znana w czasie wyświetlania inflacji. W takim przypadku masz trzy podstawowe rozwiązania, aby uniknąć ostrzeżenia:

  1. Pomiń ostrzeżenie za pomocą @Suppress
  2. Nadmuchaj widok za pomocą metody inflate widoku . To tylko otoka wokół LayoutInflater i głównie zaciemnia problem.
  3. Nadmuchać Pokaż przy użyciu LayoutInflater za pełny sposób : inflate(int resource, ViewGroup root, boolean attachToRoot). Ustaw attachToRootna. falseTo mówi inflaterowi, że rodzic nie jest dostępny. W starszych wersjach Androida Lint spowodowało to usunięcie ostrzeżenia. Nie dotyczy to już wersji Android Studio po wersji 1.0.

Zajrzyj na http://www.doubleencore.com/2013/05/layout-inflation-as-intended/, aby zapoznać się z obszerną dyskusją na ten temat, w szczególności w sekcji „Każda reguła ma wyjątek” na końcu.

emerssso
źródło
19

Rzutowanie null, gdy ViewGroup rozwiązało ostrzeżenie:

View dialogView = li.inflate(R.layout.input_layout,(ViewGroup)null);

gdzie lijest LayoutInflater'sprzedmiot.

SVL Narasimham
źródło
gdzie „li” to obiekt LayoutInflater.
SVL Narasimham
3
Ta odpowiedź jest najlepsza, pod warunkiem, że rozumiesz, DLACZEGO faktycznie to robisz. Krótka historia, jak być może już przeczytałeś, jest taka, że ​​AlertDialog nie zna swojego rodzica w czasie nadmuchu, więc jest to efekt uboczny, że szarpie rzuca ostrzeżenie w tej konkretnej sytuacji, gdy faktycznie postępujesz właściwie.
Mar Bar
Przeczytałem niezliczone odpowiedzi i strony na temat tego ostrzeżenia, ale Twoje rozwiązanie jest zdecydowanie najlepsze: proste i eleganckie
Couitchy
9
Ale to zbędny casting
mohit
11
Następnie otrzymujemy kolejne ostrzeżenie „Przesyłanie jest zbędne”!
Mousa,
17

Powinieneś użyć AlertDialog.Builder.setView(your_layout_id), więc nie musisz go nadmuchać.

Użyj AlertDialog.findViewById(your_view_id)po utworzeniu okna dialogowego.

Użyj, (AlertDialog) dialogInterfaceaby dostać się do dialogwnętrza, OnClickListenera następnie dialog.findViewById(your_view_id).

Jeffrey Chen
źródło
1
To jest odpowiednie rozwiązanie! Po prostu utwórz okno dialogowe, a następnie znajdź swój widok.
user1806772
1
To dobry sposób, jednak pamiętaj, że ta metoda została dodana w API 21
Nicolás Carrasco
A jeśli będziemy musieli przechowywać ten zawyżony układ w jakiejś zmiennej? Na przykład napisałem klasę, Aw której jest metoda onCreateDialog. W tym ostatnim napisałem, jak powiedziałeś alert_dialog_builder.setView(R.layout.edit_account_dialog);. Ale muszę przechowywać ten zawyżony układ w Azmiennej atrybutu o nazwie the_inflated_layout_of_the_dialog.
JarsOfJam-Scheduler
9

Nie musisz określać parentokna dialogowego.

Pomiń to, używając @SuppressLint("InflateParams")w górnej części zastąpienia.

kjdion84
źródło
7

Kiedy tak naprawdę nie masz żadnego parent(na przykład tworzenie widoku dla AlertDialog), nie masz innego wyjścia niż zdanie null. Zrób to więc, aby uniknąć ostrzeżenia:

final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);
Mousa
źródło
4
Generuje kolejne ostrzeżenie „wartość 'nullParent' jest zawsze pusta.”
mallaudin
Od wersji AndroidStudio 3.3 i API 28 jest to jedyne rozwiązanie, które działa.
zeeshan
1
  1. O ile wiem, AlertDialog jest jedynym przypadkiem, w którym można bezpiecznie używać wartości null zamiast widoku nadrzędnego. W takim przypadku możesz wyłączyć ostrzeżenie, używając:

    @SuppressLint ("InflateParams")

  2. Ogólnie rzecz biorąc, nigdy nie należy używać SupressLint ani jednego z obejść wymienionych w innych odpowiedziach, aby pozbyć się ostrzeżenia. Widok nadrzędny jest niezbędny do oceny parametrów układu, które są zadeklarowane w elemencie głównym rozszerzanego widoku. Oznacza to, że jeśli użyjesz null zamiast widoku nadrzędnego, wszystkie parametry układu w elemencie głównym zostaną zignorowane i zastąpione domyślnymi parametrami układu. W większości przypadków będzie dobrze, ale w niektórych przypadkach spowoduje to naprawdę trudny do znalezienia błąd.

Apfelsaft
źródło
0

Z dokumentacji View.inflate()wynika

Wypełnij widok z zasobu XML. Ta wygodna metoda otacza LayoutInflaterklasę, która zapewnia pełen zakres opcji inflacji widoku.

  @param context The Context object for your activity or application.
  @param resource The resource ID to inflate
  @param root A view group that will be the parent.  Used to properly inflate the  layout_* parameters.
Divya Gupta
źródło
0

Według https://developer.android.com/guide/topics/ui/dialogs

Napełnij i ustaw układ okna dialogowego
Przekaż null jako widok nadrzędny, ponieważ jest on umieszczany w układzie okna dialogowego

dlatego do tworzenia AlertDialog używam @SuppressLint("InflateParams")

LayoutInflater inflater = requireActivity().getLayoutInflater();
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.layout_dialog, null);
builder.setView(view);
Cor
źródło
-1

Zamiast robić

view = inflater.inflate(R.layout.list_item, null);

robić

view = inflater.inflate(R.layout.list_item, parent, false);

Napompuje go z danym rodzicem, ale nie przywiąże go do rodzica.

Podziękowania dla Coeffect ( link do jego postu )

chrześcijanin
źródło
Przydałoby się również wiedzieć, jak zdobyć rodzica.
Johan Karlsson