Objective:
Fragment can also use the Startactivityforresult method to open an activity and then process the result in its Onactivityresult method, but when fragment is nested, Because fragmentactivity bugs cause a Onactivityresult method that only recalls the fragment layer, the current fragment is not receiving results.
Bug Analysis:
Before we solve this problem, we first analyze what causes it by source code, and take the 22.2.1 version of the SUPPORT-V4 library as an example
We'll start with fragment's Startactivityforresult.
public void Startactivityforresult (Intent Intent, int requestcode) {
if (this.mactivity = null) {
throw new Illeg Alstateexception ("Fragment" + this + "not attached to activity");
} else {
this.mActivity.startActivityFromFragment (this, intent, requestcode);
}
It's obvious that the Fragmentactivity Startactivityforfragment method is directly invoked.
public void Startactivityfromfragment (Fragment Fragment, Intent Intent, int requestcode) {
if (Requestcode = 1) {
super.startactivityforresult (Intent,-1);
} else if ((Requestcode & -65536)!= 0) {
throw new IllegalArgumentException ("Can only use lower bits for REQUESTC Ode ");
} else {
Super.startactivityforresult (intent, (Fragment.mindex + 1 <<) + (Requestcode & ' \uffff '));
}
}
Here the mindex of Requestcode and fragment is merged into an integral type as the new Requestcode, then the new Requestcode's high 16 digits represent the fragment index, and the lower 16 represents the original Requestcode, Looks like this is based on fragment's mindex.
Next look at the Fragmentactivity Onactivityresult method
protected void Onactivityresult (int requestcode, int resultcode, Intent data) {THIS.M
Fragments.notestatenotsaved ();
int index = Requestcode >> 16;
if (index!= 0) {--index;
if (this.mFragments.mActive!= null && index >= 0 && Index < this.mFragments.mActive.size ()) {
Fragment Frag = (Fragment) this.mFragments.mActive.get (index); if (Frag = = null) {LOG.W ("fragmentactivity", "activity result no fragment exists for index:0x" + integer.tohexstr
ING (requestcode));
else {frag.onactivityresult (Requestcode & ' \uffff ', ResultCode, data); } else {LOG.W ("fragmentactivity", "activity result fragment index out of range:0x" + integer.tohexstring (re
Questcode));
} else {Super.onactivityresult (Requestcode, ResultCode, data); }
}
Here, take out the high 16 bits of Requestcode, 0 is the mindex of the fragment, but the next step is to find fragment directly from the fragment list of the activity, If your fragment is the quilt fragment Childfragmentmanager management of words This is absolutely cannot find, so the answer is very clear.
Solve the problem:
There are two ways to solve this problem
The first is directly upgraded SUPPORT-V4 to 23.2.0 above the version, because the 23.2.0 above to fix the bug, how to solve the specific no longer repeat the interested can study, but for various reasons could not upgrade the 23.2.0 is still a lot of
The second way is to do their own clothing, in the fragment layer rewrite the relevant methods to solve the problem
Next, the focus on the introduction of their own hands and clothing, complete implementation of the following:
public class Forresultnestedcompatfragment extends Fragment {private forresultnestedcompatfragment Forresultchildfrag
ment; @Override public void Startactivityforresult (Intent Intent, int requestcode) {Fragment parentfragment = GETPARENTFR
Agment (); if (parentfragment!= null && parentfragment instanceof forresultnestedcompatfragment) {(Forresultnestedco
mpatfragment) parentfragment). Startactivityforresultfromchildfragment (Intent, requestcode, this);
else {forresultchildfragment = null;
Super.startactivityforresult (Intent, Requestcode); } private void Startactivityforresultfromchildfragment (Intent Intent, int requestcode, forresultnestedcompatfragmen
T childfragment) {forresultchildfragment = childfragment;
Fragment parentfragment = Getparentfragment (); if (parentfragment!= null && parentfragment instanceof forresultnestedcompatfragment) {(Forresultnestedco mpatfragment) parentfragment). StartactivItyforresultfromchildfragment (Intent, requestcode, this);
else {Super.startactivityforresult (intent, Requestcode); @Override Public final void Onactivityresult (int requestcode, int resultcode, Intent data) {if (FORRESULTC
Hildfragment!= null) {Forresultchildfragment.onactivityresult (Requestcode, ResultCode, data);
Forresultchildfragment = null;
else {Onactivityresultnestedcompat (Requestcode, ResultCode, data);
} public void Onactivityresultnestedcompat (int requestcode, int resultcode, Intent data) {}}
The concrete idea One word summary is the Startactivityforresult time layer one layer evening lets the father fragment hold the child fragment the reference, When the callback Onactivityresult, the parent fragment layer by layer to the son fragment.
The specific use is to let all fragment inherit Forresultnestedcompatfragment, Then replace the Onactivityresult method with the Onactivityresultnestedcompat method.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.