Po dokonaniu jakiejś zmiany w mojej bazie danych, która pociąga za sobą znaczącą zmianę w moich widokach, chciałbym ponownie narysować, ponownie wykonać onCreate.
Jak to możliwe?
AKTUALIZACJA : Android SDK 11 dodał recreate()
metodę do działań.
Zrobiłem to, po prostu ponownie wykorzystując intencję, która zapoczątkowała działanie. Zdefiniuj intencję starterIntent
w swojej klasie i przypisz ją onCreate()
za pomocą starterIntent = getIntent();
. Następnie, gdy zechcesz wznowić aktywność, zadzwońfinish(); startActivity(starterIntent);
Nie jest to bardzo eleganckie rozwiązanie, ale jest to prosty sposób na ponowne uruchomienie aktywności i wymuszenie ponownego załadowania wszystkiego.
finish()
zaraz po tymstartActivity()
właśnie z tego powodu ...finish();
potemstartActivity(starterIntent);
Wywołaj metodę odtwarzania aktywności.
źródło
recreate()
ale teraz widzę dziwny problem, w którym przyciski radiowe nie są resetowane podczas odtwarzania, ale robią to, kiedyfinish(); startActivity(getIntent());
używam tego teraz i zobaczę, jak to działa w ciągu następnych dni lub tygodni.Łącząc tutaj niektóre odpowiedzi, możesz użyć czegoś takiego jak poniżej.
Testowanie
Trochę to przetestowałem i jest kilka problemów:
startActivity(...); finish();
po prostu istnieje aplikacji i nie powoduje ponownego uruchomienia działania.super.recreate()
w rzeczywistości nie działa tak samo, jak całkowite odtworzenie czynności. Jest to równoważne z obracaniem urządzenia, więc jeśli masz jakieśFragment
pliki,setRetainInstance(true)
nie zostaną one odtworzone; po prostu zatrzymał się i wznowił.Więc obecnie nie wierzę, że istnieje akceptowalne rozwiązanie.
źródło
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
zamiast używać11
startActivity(getIntent());finish();
nafinish();startActivity(getIntent());
opcja 1
Zadzwoń
recreate()
do swojegoActivity
. Jednak ta metoda powoduje, że podczas odtwarzania aktywności pojawia się migający czarny ekran.Opcja 2
Brak „migającego” czarnego ekranu, ale zobaczysz przejście między starymi i nowymi instancjami z niezbyt przyjemnym czarnym tłem. Możemy zrobić lepiej.
Wariant 3
Aby to naprawić, możemy dodać wywołanie do
overridePendingTransition()
:Żegnaj czarny ekran, ale w moim przypadku nadal widzę jakieś przejście (animacja zanikania), tym razem na kolorowym tle. Dzieje się tak, ponieważ kończysz bieżącą instancję swojej aktywności, zanim nowa zostanie utworzona i stanie się w pełni widoczna, a kolor pośredni jest wartością
windowBackground
atrybutu motywu.Opcja 4
Wywołanie
finish()
postartActivity()
spowoduje użycie domyślnego przejścia między czynnościami, często z małą animacją wsuwaną. Ale przejście jest nadal widoczne.Opcja 5
Dla mnie jest to najlepsze rozwiązanie, ponieważ uruchamia ponownie aktywność bez widocznego przejścia, jakby nic się nie stało.
Może to być przydatne, jeśli na przykład w swojej aplikacji ujawnisz sposób zmiany języka wyświetlania niezależnie od języka systemu. W takim przypadku za każdym razem, gdy użytkownik zmieni język aplikacji, prawdopodobnie będziesz chciał ponownie uruchomić swoją aktywność bez przejścia, dzięki czemu zmiana języka będzie wyglądać na natychmiastową.
źródło
Kiedy muszę ponownie uruchomić działanie, używam następującego kodu. Chociaż nie jest to zalecane.
źródło
dla API przed 11 nie możesz użyć recate (). Rozwiązałem w ten sposób:
i w onCreate ..
źródło
Poszukując narzędzia do piernika dla
recreate
, chciałbym użyć następujących kodów (dla pierników):W przypadku tych kodów pochodzi z implementacji w wyższym api.
Api-10 nie ma requestRelaunchActivity, jednak z różnicy znalazłem to:
Więc myślę, że mógłbym użyć
scheduleRelaunchActivity
zamiastrequestRelaunchActivity
.Napisałem je za pomocą refleksji:
Używam tych kodów do wstecznego przenoszenia platformy Xposed.
źródło
Build.VERSION_CODES.ECLAIR_MR1
(v7). Może działać również na starszych wersjach.Wywołaj
recreate()
metodę z miejsca, w którym chcesz odtworzyć swoją aktywność. Ta metoda zniszczy bieżące wystąpienie działania z,onDestroy()
a następnie ponownie utworzy działanie zonCreate()
.źródło
Jeśli to jest twój problem, prawdopodobnie powinieneś zaimplementować inny sposób wypełniania widoku w swoim działaniu. Zamiast uruchamiać ponownie
onCreate()
, powinieneś tak zrobić, aby wywołaćonCreate()
metodę wypełniania z jakimś argumentem. Gdy dane ulegną zmianie, metoda fill powinna zostać wywołana z innym argumentem.źródło
Sposób, w jaki to rozwiązałem, polega na użyciu fragmentów . Są one kompatybilne wstecz do API 4 przy użyciu biblioteki obsługi.
Tworzysz układ „opakowujący” z FrameLayout w nim.
Przykład:
Następnie tworzysz FragmentActivity, w którym możesz zamienić FrameLayout w dowolnym momencie.
Przykład:
W fragmencie, który nadmuchujesz / zastępujesz, możesz użyć onStart i onCreateView tak, jak normalnie używałbyś onCreate działania.
Przykład:
źródło
W zależności od sytuacji możesz potrzebować
getActivity().recreate();
zamiast tylkorecreate()
.Na przykład, powinieneś go używać, jeśli robisz
recreate()
w klasie, która została utworzona w klasie aktywności.źródło
Kiedyś stworzyłem aplikację testową, która przesyła, usuwa, a następnie ponownie pobiera plik bazy danych przy użyciu magazynu w chmurze Firebase. Aby wyświetlić dane w bazie danych, poniższy kod był jedynym rozwiązaniem, które znalazłem. Ani
recreate()
niefinish()
działał w tym przypadku.źródło
Znalazłem najlepszy sposób na odświeżenie Twojego fragmentu, gdy zmienią się dane
jeśli masz przycisk „szukaj”, musisz zainicjować listę ARRAY wewnątrz przycisku
mSearchBtn.setOnClickListener (new View.OnClickListener () {
@Override public void onClick (widok v) {
źródło
Jeśli chcesz przekazać parametr do onCreate (), musisz utworzyć nową intencję, dodając dodatkowe i wywołać z nią StartActivity. Oto prosty przykład, który zrobiłem w ten sposób.
źródło
Jeśli chcesz tylko powtórzyć swój pogląd, miałem dokładnie ten sam problem. W
onResume
funkcji spróbuj umieścić to:To też było w moim
onCreate()
, więc włożenie tegoonResume
zadziałało dla mnie :)źródło