Po pierwsze: tak, przeczytałem wszystkie pozostałe wątki na ten temat. I nie tylko te z tej strony ... (widzisz, jestem trochę sfrustrowany)
Większość z nich zawiera porady, których należy używać android:id
zamiast tylko id
w pliku XML. Zrobiłem.
Nauczyłem się od innych, że View.findViewById
działa inaczej niż Activity.findViewById
. Ja też sobie z tym poradziłem.
W moim location_layout.xml
używam:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="@+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
W swojej działalności wykonuję:
...
setContentView( R.layout.location_layout );
i w mojej niestandardowej klasie widoku:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
który zwraca null
. Dzięki temu moja aktywność działa dobrze. Więc może to ze względu na Activity.findViewById
i View.findViewById
różnic. Zapisałem więc kontekst przekazany lokalnie do konstruktora widoku celnego i próbowałem:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
który również wrócił null
.
Następnie zmieniłem widoku niestandardowego rozszerzenia ViewGroup
zamiast View
i zmienił location_layout.xml
pozwolić TextView
być bezpośrednim dziecko mojego widoku niestandardowego, tak że View.findViewById
powinno działać jak przypuszczano. Zaskocz: nic nie rozwiązało.
Co do cholery robię źle?
Będę wdzięczny za wszelkie komentarze.
źródło
Odpowiedzi:
Być może dlatego, że dzwonisz za wcześnie. Poczekaj, aż
onFinishInflate()
. Oto przykładowy projekt demonstrujący niestandardowyView
dostęp do jego zawartości.źródło
onFinishInflate()
.Być może dzwonisz
findViewById
przed telefonemsetContentView
? W takim przypadku spróbuj zadzwonićfindViewById
PO telefonowaniusetContentView
źródło
Upewnij się, że nie masz wielu wersji swojego układu dla różnych gęstości ekranu. Natknąłem się na ten problem podczas dodawania nowego identyfikatora do istniejącego układu, ale zapomniałem zaktualizować wersję HDpi. Jeśli zapomnisz zaktualizować wszystkie wersje pliku układu, będzie on działał dla niektórych gęstości ekranu, ale nie dla innych.
źródło
FindViewById może mieć wartość NULL, jeśli wywołasz niewłaściwy superkonstruktor w widoku niestandardowym. Tag ID jest częścią attrs, więc jeśli zignorujesz attrs, usuniesz identyfikator.
To by było złe
To jest poprawne
źródło
W moim przypadku miałem 2 działania w moim projekcie
main.xml
imain2.xml
. Od samego początkumain2
było kopiąmain
, i wszystko działało dobrze, dopóki nie dodałem nowyTextView
domain2
, więcR.id.textview1
stał się dostępny dla reszty aplikacji. Następnie próbowałem pobrać go za pomocą standardowego wywołania:i zawsze było zero. Okazało się, że w
onCreate
konstruktorze nie tworzyłem instancjimain2
, ale drugą. Miałem:zamiast
Zauważyłem to po przyjeździe tutaj na stronie.
źródło
Oprócz klasycznych przyczyn wymienionych w innym miejscu:
setContentView()
wcześniejfindViewById()
id
chcesz mieć widok lub układ, który podałeśsetContentView()
id
nie jest przypadkowo powielony w różnych układachZnalazłem jeden dla niestandardowych widoków w standardowych układach, który jest sprzeczny z dokumentacją:
Teoretycznie możesz utworzyć niestandardowy widok i dodać go do układu ( patrz tutaj ). Odkryłem jednak, że w takich sytuacjach czasami
id
atrybut działa dla wszystkich widoków w układzie oprócz tych niestandardowych. Rozwiązaniem, którego używam jest:FrameLayout
o takich samych właściwościach układu, jakie chcesz mieć w widoku niestandardowym. Daj temu odpowiedniid
, powiedzmyframe_for_custom_view
.W
onCreate
:co umieszcza niestandardowy widok w ramce.
źródło
źródło
Odpowiedź dla tych, którzy używają ExpandableListView i napotkasz to pytanie na podstawie jego tytułu.
Wystąpił ten błąd podczas próby pracy z TextView w widoku potomnym i grupowym w ramach implementacji ExpandableListView.
W implementacjach metod getChildView () i getGroupView () można użyć czegoś takiego jak poniżej.
Znalazłem to tutaj .
źródło
Jestem całkiem nowy w Android / Eclipse, przez pomyłkę dodałem rzeczy interfejsu użytkownika
activity_main.xml
zamiastfragment_main.xml
. Zajęło mi to kilka godzin, żeby to rozgryźć ...źródło
FWIW, nie widzę, aby ktokolwiek rozwiązał to w taki sam sposób, jak potrzebowałem. Brak skarg w czasie kompilacji, ale w czasie wykonywania otrzymywałem zerowy widok i wzywałem rzeczy we właściwej kolejności. Oznacza to findViewById () po setContentView (). Problem okazał się, że mój widok jest zdefiniowany w content_main.xml, ale w mojej activity_main.xml brakowało mi tej jednej instrukcji:
Kiedy dodałem to do activity_main.xml, nie ma już NullPointer.
źródło
Miałem ten sam problem. Korzystałem z biblioteki innej firmy, która pozwala zastąpić ich adapter dla GridView i określić własny układ dla każdej komórki GridView.
W końcu zrozumiałem, co się dzieje. Zaćmienie nadal używało pliku xml układu biblioteki dla każdej komórki w GridView, chociaż nie dawało tego żadnej wskazówki. W moim niestandardowym adapterze oznaczało, że korzysta z zasobu xml z mojego własnego projektu, chociaż w czasie wykonywania tak nie było.
Więc upewniłem się, że moje niestandardowe układy i identyfikatory XML różnią się od tych, które wciąż siedzą w bibliotece, wyczyściłem projekt, a następnie zacząłem czytać prawidłowe niestandardowe układy, które były w moim projekcie.
Krótko mówiąc, należy zachować ostrożność, jeśli przesłonisz adapter biblioteki innej firmy i określisz własny układ xml dla adaptera do użycia. Jeśli układ w projekcie ma taką samą nazwę pliku jak w bibliotece, możesz napotkać naprawdę trudny do znalezienia błąd!
źródło
W moim szczególnym przypadku próbowałem dodać stopkę do ListView. Następujące wywołanie funkcji onCreate () zwracało wartość null.
Zmiana tego ustawienia, aby nadmuchać widok stopki zamiast znajdowania go według ID, rozwiązała ten problem.
źródło
W moim przypadku korzystałem z ExpandableListView i ustawiłem
android:transcriptMode="normal"
. Powodowało to zniknięcie kilku dzieci w rozszerzalnej grupie i uzyskiwałem wyjątek NULL, gdy tylko przewijałem listę.źródło
Dla mnie miałem dwa układy XML dla tej samej aktywności - jeden w trybie pionowym i jeden w układzie poziomym. Oczywiście zmieniłem identyfikator obiektu w xml krajobrazowym, ale zapomniałem dokonać tej samej zmiany w wersji portretowej. Upewnij się, że jeśli zmienisz jeden, zrobisz to samo z drugim xml, inaczej nie pojawi się błąd, dopóki go nie uruchomisz / nie debugujesz i nie będzie mógł znaleźć identyfikatora, którego nie zmieniłeś. Och głupie błędy, dlaczego musisz mnie tak karać?
źródło
Ustaw zawartość działania z zasobu układu. tj.,
setContentView(R.layout.basicXml)
;źródło
Oprócz powyższych rozwiązań
tools:context=".TakeMultipleImages"
upewniasz się, że układ ma taką samą wartość w pliku mainfest.xml:android:name=".TakeMultipleImages"
dla tego samego elementu aktywności. ma to miejsce, gdy używasz funkcji kopiuj i wklej, aby utworzyć nową aktywnośćźródło
Mam ten sam problem, ale myślę, że warto się z wami podzielić. Jeśli musisz znaleźćViewById w niestandardowym układzie, na przykład:
nie można uzyskać widoku w konstruktorze. Powinieneś wywołać findViewById po zawyżeniu widoku. Jest to metoda, którą można zastąpić
onFinishInflate
źródło
Chciałem tu wrzucić moją konkretną sprawę. Może pomóc komuś w dalszej linii.
Użyłem tej dyrektywy w moim XML UI dla Androida w następujący sposób:
Widok rodzica:
Widok dziecka (przycisk ponawiania):
.findViewById (R.id.retry) zawsze zwraca wartość null. Ale jeśli przeniosłem identyfikator z widoku potomnego do tagu dołączania, zaczął on działać.
Naprawiony rodzic:
Naprawiono dziecko:
źródło
Mój przypadek jest taki jak wyżej, żadne rozwiązania nie działały. Zakładam, że mój widok był zbyt głęboko w hierarchii układu. Przeniosłem go o jeden poziom wyżej i nie był już zerowy.
źródło
W moim przypadku zawyżyłem układ, ale widoki dzieci wracają do zera. Pierwotnie miałem to:
Kiedy jednak zmieniłem go na następujący, zadziałało:
Kluczem było konkretne odniesienie do już zawyżonego układu, aby uzyskać widoki dziecka. To znaczy, aby dodać
footerView
:źródło
Z mojego doświadczenia wynika, że może się to zdarzyć również wtedy, gdy twój kod jest wywoływany po OnDestroyView (gdy fragment znajduje się na tylnym stosie). Jeśli aktualizujesz interfejs użytkownika na wejściu z BroadCastReceiver, powinieneś sprawdzić, czy tak jest .
źródło
NAPEŁNIJ UKŁAD !! (który zawiera identyfikator)
W moim przypadku findViewById () zwrócił null, ponieważ układ, w którym element został zapisany, nie został zawyżony ...
Na przykład. fragment_layout.xml
findViewById (R.id.listview) zwrócił wartość null, ponieważ nie wykonałem inflater.inflate (R.layout.fragment_layout, ..., ...); przed tym.
Mam nadzieję, że ta odpowiedź pomoże wam wszystkim.
źródło
Moją poprawką było po prostu wyczyszczenie projektu.
źródło
findViewById może również zwrócić null, jeśli znajdujesz się we fragmencie. Jak opisano tutaj: findViewById we fragmencie
Powinieneś wywołać metodę getView (), aby zwrócić widok najwyższego poziomu wewnątrz fragmentu. Następnie możesz znaleźć elementy układu (przyciski, widoki tekstu itp.)
źródło
Próbowałem wszystkiego powyższego, nic nie działało .. więc musiałem ustawić statyczny obraz ImageView,
public static ImageView texture;
a potemtexture = (ImageView) findViewById(R.id.texture_back);
nie sądzę, że to dobre podejście, ale to naprawdę działało w moim przypadku :)źródło
W moim przypadku findViewById zwrócił wartość null, gdy przeniosłem wywołanie z obiektu nadrzędnego do obiektu adaptera utworzonego przez obiekt nadrzędny. Po wypróbowaniu wymienionych tutaj sztuczek bezskutecznie przeniosłem findViewById z powrotem do obiektu nadrzędnego i przekazałem wynik jako parametr podczas tworzenia instancji obiektu adaptera. Na przykład zrobiłem to w obiekcie nadrzędnym:
Następnie przekazałem hdSpinner jako parametr podczas tworzenia obiektu adaptera:
źródło
Awaria dla mnie, ponieważ jedno z pól w moim identyfikatorze aktywności było zgodne z identyfikatorem w innej aktywności. Naprawiłem to, podając unikalny identyfikator.
W moim loginActivity.xml pole hasła to „hasło”. W mojej działalności rejestracyjnej właśnie to naprawiłem, podając id r_password, a następnie nie zwrócił obiektu zerowego:
źródło
Napotkałem podobny problem, gdy próbowałem zrobić niestandardowy widok dla
ListView
.Rozwiązałem to po prostu przez zrobienie tego:
źródło
Sposoby debugowania i znalezienia problemu:
W moim przypadku korzystałem z activity_main.xml zarówno w module aplikacji, jak i module biblioteki. Więc kiedy wykonałem powyższe kroki, zamiast układu, który zaprojektowałem w bibliotece, układ wewnątrz modułu aplikacji został zawyżony.
Więc zmieniłem nazwę pliku activity_main.xml na activity_main_lib.xml.
Więc upewnij się, że nie mają żadnych zduplikowane nazwy układu w całym projekcie .
źródło