Skip to content

Instantly share code, notes, and snippets.

@jnagels
Last active January 30, 2018 05:44
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jnagels/8415902 to your computer and use it in GitHub Desktop.
Save jnagels/8415902 to your computer and use it in GitHub Desktop.
StartActivityForResult with nested Fragments
public abstract class AbstractActivity extends FragmentActivity implements FragmentUtils.ActivityForResultStarter
{
private SparseArray<Bundle> requests;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null)
{
this.requests = new SparseArray<Bundle>();
}
else
{
this.requests = savedInstanceState.getSparseParcelableArray("requests");
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSparseParcelableArray("requests", this.requests);
}
@Override
public void startActivityForResultWhileSavingOrigin(int requestCode, Intent intent, int[] indices)
{
//special method for start an activity for result.
//we save the information about where this request comes from in a bundle and store it based on requestCode
final Bundle bundle = new Bundle();
bundle.putInt("code", requestCode);
bundle.putParcelable("intent", intent);
bundle.putIntArray("indices", indices);
this.requests.put(requestCode, bundle);
this.startActivityForResult(intent, requestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//first check if we saved any data about the origin of this request (which fragment)
final Bundle request = this.requests.get(requestCode, null);
if (request != null)
{
//find the indices-array
final int[] indices = request.getIntArray("indices");
FragmentManager fm = this.getSupportFragmentManager();
Fragment f = null;
//loop backwards
for(int i = indices.length - 1 ; i >= 0 ; i--)
{
if (fm != null)
{
//find a list of active fragments
List<Fragment> flist = fm.getFragments();
if (flist != null && indices[i] < flist.size())
{
f = flist.get(indices[i]);
fm = f.getChildFragmentManager();
}
}
}
//we found our fragment that initiated the request to startActivityForResult, give it the callback!
if (f != null)
{
f.onActivityResult(requestCode, resultCode, data);
return ;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
public abstract class AbstractFragment extends android.support.v4.app.Fragment
{
@Override
public void startActivityForResult(Intent intent, int requestCode) {
FragmentUtils.startActivityForResultWhileSavingOrigin(this, requestCode, intent, null);
}
}
public class FragmentUtils
{
public interface ActivityForResultStarter
{
void startActivityForResultWhileSavingOrigin(int requestCode, Intent intent, int[] indices);
}
/**
* Start an activity for result.
* This method keeps track of all the fragment-indexes inside the active fragments.
* @param fragment
* @param requestCode
* @param intent
* @param indices
*/
public final static void startActivityForResultWhileSavingOrigin(Fragment fragment, int requestCode, Intent intent, int[] indices)
{
//get a list of all the active fragments
final List<Fragment> fragments = fragment.getFragmentManager().getFragments();
if (fragments != null)
{
//find the index of this fragment inside the active list
final int index = fragments.indexOf(fragment);
if (indices == null)
{
indices = new int[1];
}
else
{
//enlarge the array
int[] newIndices = new int[indices.length + 1];
System.arraycopy(indices, 0, newIndices, 0, indices.length);
indices = newIndices;
}
//save our index on the last part
indices[indices.length - 1] = index;
if (fragment.getParentFragment() != null)
{
//if there is a parent fragment, we call this method again but with the parent fragment
startActivityForResultWhileSavingOrigin(fragment.getParentFragment(), requestCode, intent, indices);
}
else if (fragment.getActivity() != null && fragment.getActivity() instanceof ActivityForResultStarter)
{
//there is no parent fragment, it must mean we are at the activity-level, so start it from there!
((ActivityForResultStarter)fragment.getActivity()).startActivityForResultWhileSavingOrigin(requestCode, intent, indices);
}
else
{
//nothing else is available, just start it normally
fragment.startActivityForResult(intent, requestCode);
}
}
else
{
//there are no active fragments, just start it normally
fragment.startActivityForResult(intent, requestCode);
}
}
}
@shalinipk
Copy link

Thank you for saving my day - well, half a day.
I had to add this line in onActivityResult though- "requestCode &= 0xffff;" to get it working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment