Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onActivityResult() not called in new nested fragment API

I have been using the new nested fragment API that Android includes in the support library.

The problem that I am facing with nested fragments is that, if a nested fragment (that is, a fragment that has been added to another fragment via the FragmentManagerreturned by getChildFragmentManager()) calls startActivityForResult(), the nested fragment's onActivityResult() method is not called. However, both the parent fragment's onActivityResult() and activity's onActivityResult() do get called.

I don't know if I am missing something about nested fragments, but I did not expect the described behavior. Below is the code that reproduces this problem. I would very much appreciate if someone can point me in the right direction and explain to me what I am doing wrong:

package com.example.nestedfragmentactivityresult;  import android.media.RingtoneManager; import android.os.Bundle; import android.content.Intent; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast;  public class MainActivity extends FragmentActivity {     public void onCreate(Bundle savedInstanceState)     {         super.onCreate(savedInstanceState);         this.getSupportFragmentManager()             .beginTransaction()             .add(android.R.id.content, new ContainerFragment())             .commit();     }      public void onActivityResult(int requestCode, int resultCode, Intent data)     {         super.onActivityResult(requestCode, resultCode, data);          // This is called         Toast.makeText(getApplication(),             "Consumed by activity",             Toast.LENGTH_SHORT).show();     }      public static class ContainerFragment extends Fragment     {         public final View onCreateView(LayoutInflater inflater,                                        ViewGroup container,                                        Bundle savedInstanceState)         {             View result = inflater.inflate(R.layout.test_nested_fragment_container,                 container,                 false);              return result;         }          public void onActivityCreated(Bundle savedInstanceState)         {             super.onActivityCreated(savedInstanceState);             getChildFragmentManager().beginTransaction()                 .add(R.id.content, new NestedFragment())                 .commit();         }          public void onActivityResult(int requestCode,                                      int resultCode,                                      Intent data)         {             super.onActivityResult(requestCode, resultCode, data);              // This is called             Toast.makeText(getActivity(),                 "Consumed by parent fragment",                 Toast.LENGTH_SHORT).show();         }     }      public static class NestedFragment extends Fragment     {         public final View onCreateView(LayoutInflater inflater,                                        ViewGroup container,                                        Bundle savedInstanceState)         {             Button button = new Button(getActivity());             button.setText("Click me!");             button.setOnClickListener(new View.OnClickListener()             {                 public void onClick(View v)                 {                     Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);                     startActivityForResult(intent, 0);                 }             });              return button;         }          public void onActivityResult(int requestCode,                                      int resultCode,                                      Intent data)         {             super.onActivityResult(requestCode, resultCode, data);              // This is NOT called             Toast.makeText(getActivity(),                 "Consumed by nested fragment",                 Toast.LENGTH_SHORT).show();         }     } } 

test_nested_fragment_container.xml is:

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:id="@+id/content"     android:layout_width="match_parent"     android:layout_height="match_parent" >  </FrameLayout> 
like image 568
Knuckles the Echidna Avatar asked Nov 27 '12 08:11

Knuckles the Echidna


People also ask

Can I use onActivityResult in fragment?

Since Activity gets the result of onActivityResult() , you will need to override the activity's onActivityResult() and call super. onActivityResult() to propagate to the respective fragment for unhandled results codes or for all.

Can we use onActivityResult in fragment Android?

Android Intent Getting a result from Activity to FragmentReceiving the result can be done using the Fragment 's method onActivityResult() . You need to make sure that the Fragment's parent Activity also overrides onActivityResult() and calls it's super implementation.

What can I use instead of Startactivity for results?

But recently startActivityForResult() method is deprecated in AndroidX. Android came up with ActivityResultCallback (also called Activity Results API) as an alternative for it. Step 1: You just have to create an ActivityResultLauncher and pass following parameters handle onActivityResult in it as shown above.


1 Answers

I solved this problem with the following code (support library is used):

In container fragment override onActivityResult in this way:

@Override     public void onActivityResult(int requestCode, int resultCode, Intent data) {         super.onActivityResult(requestCode, resultCode, data);          List<Fragment> fragments = getChildFragmentManager().getFragments();         if (fragments != null) {             for (Fragment fragment : fragments) {                 fragment.onActivityResult(requestCode, resultCode, data);             }         }     } 

Now nested fragment will receive call to onActivityResult method.

Also, as noted Eric Brynsvold in similar question, nested fragment should start activity using it's parent fragment and not the simple startActivityForResult() call. So, in nested fragment start activity with:

getParentFragment().startActivityForResult(intent, requestCode); 
like image 88
pvshnik Avatar answered Sep 22 '22 00:09

pvshnik