Działanie, w którym znajduje się ten fragment, ma swoją onActivityResult
nazwę, gdy powraca aktywność kamery.
Mój fragment rozpoczyna działanie dla rezultatu z zamiarem wysłania zdjęcia do aparatu. Aplikacja do obrazu ładuje się dobrze, robi zdjęcie i wraca. onActivityResult
Jednak nigdy nie jest trafiony. Ustawiłem punkty przerwania, ale nic się nie uruchamia. Czy fragment może mieć onActivityResult
? Tak mi się wydaje, ponieważ jest to zapewniona funkcja. Dlaczego to się nie uruchamia?
ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, 1888);
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if( requestCode == 1888 ) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
}
}
requestCode >= 0
!Odpowiedzi:
Działalność hostingu zastępuje
onActivityResult()
, ale niesuper.onActivityResult()
wywołała nieobsługiwanych kodów wynikowych. Najwyraźniej, mimo że fragment jest tym, który wykonujestartActivityForResult()
połączenie, aktywność otrzymuje pierwsze podejście do obsługi wyniku. Ma to sens, gdy weźmie się pod uwagę modułowość fragmentów. Kiedy zaimplementowałemsuper.onActivityResult()
dla wszystkich nieobsługiwanych wyników, fragment miał szansę na obsługę wyniku.A także z odpowiedzi @siqing:
Aby uzyskać wynik w swoim fragmencie, upewnij się, że dzwonisz
startActivityForResult(intent,111);
zamiastgetActivity().startActivityForResult(intent,111);
w swoim fragmencie.źródło
getParentFragment().startActivityForResult
aby fragment nadrzędny miał wywołaną metodę onActivityResult.Myślę, że zadzwoniłeś
getActivity().startActivityForResult(intent,111);
. Powinieneś zadzwonićstartActivityForResult(intent,111);
.źródło
RingtonePreference
lokalizacją wPreferenceFragment
. NiestetyRingtonePreference
dzwonigetActivity().startActivityForResult()
i nie otrzymałem wyników, mimo że dzwonięsuper.onActivityResult
do działaniaonActivityResult
. Byłem zmuszony stworzyć pochodną zRingtonePreference
klasy, która wiąże się zPreferenceFragment
wywołaniami ifragment.startActivityForResult()
.Opcja 1:
Jeśli dzwonisz
startActivityForResult()
z fragmentu, powinieneś zadzwonićstartActivityForResult()
, niegetActivity().startActivityForResult()
, ponieważ spowoduje to fragment onActivityResult ().Jeśli nie masz pewności, gdzie dzwonisz
startActivityForResult()
i jak będziesz dzwonić metodami.Opcja 2:
Ponieważ działanie otrzymuje wynik
onActivityResult()
, musisz zastąpić działanieonActivityResult()
i wywołaćsuper.onActivityResult()
propagację do odpowiedniego fragmentu dla nieobsługiwanych kodów wyników lub dla wszystkich.Jeśli powyższe dwie opcje nie działają, zapoznaj się z opcją 3, ponieważ na pewno zadziała.
Opcja 3:
Wyraźne wywołanie z fragmentu do funkcji onActivityResult jest następujące.
W nadrzędnej klasie Activity należy zastąpić metodę onActivityResult (), a nawet zastąpić ją w klasie Fragment i wywołać jako poniższy kod.
W klasie nadrzędnej:
W klasie dziecięcej:
źródło
setResult(); finish();
kiedy odsuwam się od drugiej aktywności, wtedyonActivityResult
zostaje również wywołany z pod warunkiemRESULT_CODE
.onActivityResult()
działanie zwraca wartość dziwną,requestCode
która jest przekazywana do mojego fragmentu, a następnie ignorowana = /Jeśli nie znasz fragmentów swojej aktywności, po prostu wylicz je wszystkie i wyślij argumenty wyniku działania:
źródło
Mam ten sam problem z
ChildFragmentManager
. Menedżer nie przekaże wyniku do zagnieżdżonego fragmentu, musisz to zrobić ręcznie we fragmencie podstawowym.źródło
Fragment fragment = myChildFragment;
aby zastąpić powyższąfindFragmentByTag
linię kodu. Resztę można zachować bez zmian.Oryginalny post.
FragmentActivity
zastępujerequestCode
zmodyfikowanym. Następnie, kiedyonActivityResult()
zostanie wywołany,FragmentActivity
analizuje wyższe 16 bitów i przywraca indeks oryginalnego fragmentu. Spójrz na ten schemat:Jeśli masz kilka fragmentów na poziomie katalogu głównego, nie ma żadnych problemów. Ale jeśli masz zagnieżdżone fragmenty , na przykład
Fragment
z kilkoma zakładkami w środkuViewPager
, masz gwarancję , że napotkasz problem (lub już się z nim spotkałeś).Ponieważ w środku jest przechowywany tylko jeden indeks
requestCode
. To jest indeksFragment
jego wnętrzaFragmentManager
. Kiedy używamy zagnieżdżonych fragmentów, istnieją dzieciFragmentManager
, które mają własną listę fragmentów. Konieczne jest więc zapisanie całego łańcucha indeksów, poczynając od katalogu głównegoFragmentManager
.Jak rozwiązujemy ten problem? W tym poście jest typowe rozwiązanie obejścia .
GitHub: https://github.com/shamanland/nested-fragment-issue
źródło
To jeden z najpopularniejszych problemów. Możemy znaleźć wiele wątków na ten temat. Ale żaden z nich nie jest użyteczny dla MNIE.
Rozwiązałem ten problem za pomocą tego rozwiązania.
Najpierw zrozummy, dlaczego tak się dzieje.
Możemy
startActivityForResult
sprawdzać bezpośrednio z Fragmentu, ale tak naprawdę mechanika z tyłu jest obsługiwana przez Aktywność.Kiedy zadzwonisz
startActivityForResult
z fragmentu, requestCode zostanie zmieniony, aby dołączyć tożsamość fragmentu do kodu. Pozwoli to Activity śledzić, kto wysłał to żądanie po otrzymaniu wyniku.Po cofnięciu działania, wynik zostanie wysłany do działania onActivityResult ze zmodyfikowanym kodem requestCode, który zostanie zdekodowany do pierwotnego kodu requestCode + fragmentu. Następnie działanie wyśle wynik działania do tego fragmentu za pośrednictwem onActivityResult. I wszystko skończone.
Problemem jest:
Aktywność może wysłać wynik tylko do fragmentu, który został dołączony bezpośrednio do działania, ale nie do zagnieżdżonego. To jest powód, dla którego onActivityResult zagnieżdżonego fragmentu nigdy nie zostałby nazwany bez względu na wszystko.
Rozwiązanie:
1) Rozpocznij zamiar w swoim fragmencie, wykonując poniższy kod:
2) Teraz w zastąpieniu Aktywności nadrzędnej **
onActivityResult()
: **Musisz wywołać to w działaniu nadrzędnym, aby to zadziałało.
3) W wywołaniu fragmentu:
Otóż to. Dzięki temu rozwiązaniu można go zastosować do każdego pojedynczego fragmentu, niezależnie od tego, czy jest zagnieżdżony czy nie. I tak, obejmuje to również całą sprawę! Co więcej, kody są również ładne i czyste.
źródło
DLA WIELU ZNISZCZONYCH FRAGMENTÓW (na przykład podczas korzystania z ViewPager we fragmencie)
W swojej głównej działalności :
W twoim fragmencie:
W zagnieżdżonym fragmencie
Zadzwoń do aktywności
UniqueInstanceInt - zamień go na int, który jest unikalny wśród zagnieżdżonych fragmentów, aby zapobiec traktowaniu odpowiedzi przez inny fragment.
Otrzymać odpowiedź
Uwaga
Aby uniknąć błędu, należy użyć liczby od 0 do 65536 w unikatowejInstanceInt, aby uniknąć błędu „Można użyć tylko 16 mniejszych bitów dla kodu żądania”.
źródło
Mogę dodać dwie porady, jeśli ktoś nadal nie może tego zrobić. W pliku Manifest.xml upewnij się, że działanie hostingu nie zakończyło się po oddzwonieniu, a działanie do uruchomienia ma standardowo tryb uruchamiania. Zobacz szczegóły jak poniżej:
W przypadku działalności Hosting ustaw właściwość no history na false, jeśli tak
Aby rozpocząć działanie, ustaw tryb uruchamiania jako standard, jeśli masz
źródło
Miałem również ten sam problem, kiedy przeniosłem ten blok kodu poza fragment do klasy użyteczności ,
parentActivity
przekazując go jako argument ,Wtedy nie otrzymałem żadnej wartości w
onActivityResult
metodzie tego fragmentu , potem zmieniłem argument na Fragment , więc zmieniona definicja metody wyglądała następująco:Potem udało mi się uzyskać wartość w
onActivityResult
sprawie Fragmentźródło
Problem ten spotkałem również we fragmencie. I zadzwoniłem
startActivityForResult
doDialogFragment
.Ale teraz ten problem został rozwiązany:
FragmentClassname.this.startActivityForResult
.źródło
startActivityForResult(...)
z klasy abstrakcyjnej w kodzie fragmentu.DLA NESTED FRAGMENTS (na przykład podczas korzystania z ViewPager)
W swojej głównej działalności:
W głównym fragmencie najwyższego poziomu (fragment ViewPager):
W YourFragment (zagnieżdżony fragment):
źródło
W moim przypadku był to błąd Androida ( http://technet.weblineindia.com/mobile/onactivityresult-not-get-getting-called-in-nested-fragments-android/ ), jeśli używasz obsługiwanego
FragmentActivity
, musisz użyćgetSupportFragmentManager
zamiastgetChildFragmentManager
:źródło
W skrócie,
We fragmencie deklaruj
Fragment fragment = this
;po tym użyciu
fragment.startActivityForResult
.Wynik powróci w activityResult.
źródło
Rozwiązanie 1:
Zadzwoń
startActivityForResult(intent, REQUEST_CODE);
zamiastgetActivity().startActivityForResult(intent, REQUEST_CODE);
.Rozwiązanie 2:
Kiedy
startActivityForResult(intent, REQUEST_CODE);
się nazywa,onActivityResult(requestCode,resultcode,intent)
wywoływana jest aktywność , a następnie możesz zadzwonićfragments onActivityResult()
stąd, przekazującrequestCode, resultCode and intent
.źródło
Zadzwoń do swojego fragmentu
gdzie
this
odnosi się do fragmentu. W przeciwnym razie wykonaj, jak powiedział @Clevester:Musiałem także zadzwonić
w działaniu nadrzędnym,
onActivityResult
aby działało.(Dostosowałem tę odpowiedź z odpowiedzi @ Clevester.)
źródło
Dla tych, którzy korzystają z Android Nawigacja Komponent powinien używać w aktywny na dostać to fragment odniesienia i na wezwanie fragment .
onActivityResult(...)
primaryNavigationFragment
fragment.onActivityResult(...)
Oto aktywność
onActivityResult(...)
źródło
Większość z tych odpowiedzi wciąż powtarzają, że trzeba zadzwonić
super.onActivityResult(...)
w hostaActivity
dla TwojegoFragment
. Ale to chyba nie działało dla mnie.Więc w swoim hoście
Activity
powinieneś zadzwonićFragments
onActivityResult(...)
zamiast tego. Oto przykład.W pewnym momencie swojego
HostActivity
trzeba będzie przypisać używasz. Lub użyj, aby uzyskać zamiast trzymać odniesienie do niego w swoim . Sprawdź także, zanim spróbujesz zadzwonić .this.myFragment
Fragment
FragmentManager
Fragment
HostActivity
null
this.myFragment.onActivityResult(...);
źródło
źródło
Możesz po prostu zastąpić BaseActivity
onActivityResult
na fragmenciebaseActivity.startActivityForResult
.W BaseActivity dodaj interfejs i przesłoń onActivityResult.
Narzędzie Fragment
OnBaseActivityResult
To obejście załatwi sprawę.
źródło
Jeśli napotkasz powyższy problem przy logowaniu na Facebooku , możesz użyć poniższego kodu w czynności nadrzędnej swojego fragmentu, takiej jak:
Lub:
I dodaj poniższe wezwanie w swoim fragmencie ...
źródło
Kolejny przypadek użycia, który nie został jeszcze opisany w innych odpowiedziach:
onActivityResult()
zadeklarowane we fragmencie nie jest wywoływane przy użyciuexception.startResolutionForResult()
:W takim przypadku zastąp
exception.startResolutionForResult()
fragmentemstartIntentSenderForResult()
:źródło
Wersja Kotlin (W twojej aktywności onActivityResult ())
źródło
Jak wspomniano Ollie C, istnieje aktywny błąd biblioteki wsparcia, który używa zwracanych wartości do onActivityResult, gdy używasz zagnieżdżonych fragmentów. Właśnie w to uderzyłem :-(.
Zobacz Fragment.onActivityResult nie wywoływany, gdy requestCode! = 0 .
źródło
Mam głębokie podejrzenie, że wszystkie odpowiedzi tutaj są niczym innym jak hackami. Próbowałem ich wszystkich i wielu innych, ale bez żadnych wiarygodnych wniosków, ponieważ zawsze istnieje jakiś głupi problem. Nie mogę polegać na niespójnych wynikach. Jeśli spojrzysz na oficjalną dokumentację API Androida dla Fragmentów, zobaczysz, że Google wyraźnie stwierdza, co następuje:
Zobacz: Android Fragment API
Wydaje się więc, że najbardziej poprawnym i niezawodnym podejściem byłoby faktycznie wywołanie metody startActivityForResult () z działania hosta, a także obsłużenie wynikowej funkcji onActivityResult () .
źródło
mActivity.startActivityFromFragment(this, intent, requestCode)
- więc nie jest to nic innego, jak wygodne opakowanieTwój kod ma zagnieżdżony fragment. Wywołanie super.onActivityForResult nie działa
Nie chcesz modyfikować wszystkich działań, z których można wywoływać twój fragment, ani nie pracować nad wywołaniem każdego fragmentu w łańcuchu fragmentów.
Oto jedno z wielu działających rozwiązań. utwórz fragment w locie i połącz go bezpośrednio z działaniem za pomocą menedżera fragmentów wsparcia. Następnie wywołaj startActivityForResult z nowo utworzonego fragmentu.
źródło
Mój problem polegał na działaniu hosta. Znalazłem go z zestawem.
android:launchMode="standard"
Usunąłem go tymczasowo i działa!źródło
onActivityResult nie będzie działać, jeśli tryb uruchamiania ustawiony jest na SingleInstance lub SingleTask. lub nazywasz swoją aktywność za pomocą IntentFilters
standard
lubsingleTop
tryb uruchamiania będzie działał dobrze.źródło
Jeśli używasz zagnieżdżonych fragmentów, działa to również:
Oprócz tego musisz zadzwonić
super.onActivityResult
z aktywności rodzica i wypełnićonActivityResult
metodę fragmentu.źródło
Poradziłem sobie z tym, pisząc klasę podstawową, która się rozszerza
Fragment
, awonactivityresult
ramach działania zidentyfikowałem aktualnie działający fragment za pomocąfragmenttag
. Następnie wywołuję metodę zdefiniowaną przez użytkownika w klasie fragmentbase. Spowoduje to uruchomienie zdarzenia w aktualnie uruchomionym fragmencie.źródło