QWERTY
QWERTY

Reputation: 2315

Android pass value from child fragment back to parent fragment

I was having some problem when trying to get the value from fragment upon dismiss. My fragment A will open up fragment B, when the button in fragment B is clicked, I wanted to get a value and pass back to fragment A to be displayed. However, I am not sure how to do it.

Fragment A:

@Click(R.id.buttonAttach)
void buttonAttachClicked(View v){
        SupportAttachFileFragment fragment = new SupportAttachFileFragment_();
        fragment.show(getFragmentManager(), null);

        // get value here and display
        textViewLogCounter.setText();
    }
}

Fragment B:

When this button onClicked, I wanted to pass the value back to fragment A and display.

@Click(R.id.buttonAttach)
void buttonAttachClicked(View v){
    System.out.println("TOTAL " + selectedRows.size());
    dismiss();
}

I not sure how to do it. I was thinking of Bundle but Bundle is to pass parameter to a new activity. In this case, my fragment is already opened but I wanted to pass some values back.

Any ideas? Thanks!

Upvotes: 5

Views: 6336

Answers (3)

Mayank Bhatnagar
Mayank Bhatnagar

Reputation: 2191

All Fragment-to-Fragment communication is done either through a shared ViewModel or through the associated Activity. Two Fragments should never communicate directly.

Different ways for fragment to fragment communication:

  1. The recommended way to communicate between fragments is to create a shared ViewModel object. Both fragments can access the ViewModel through their containing Activity. The Fragments can update data within the ViewModel and if the data is exposed using LiveData the new state will be pushed to the other fragment as long as it is observing the LiveData from the ViewModel. To see how to implement this kind of communication, read the 'Share data between Fragments' section in the ViewModel guide.

  2. You can define an interface in the Fragment class and implement it within the Activity. The Fragment captures the interface implementation during its onAttach() lifecycle method and can then call the Interface methods in order to communicate with the Activity.

    public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }
    
    ...
    

    }

Now the fragment can deliver messages to the activity by calling the onArticleSelected() method (or other methods in the interface) using the mCallback instance of the OnHeadlineSelectedListener interface.

For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.

@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Send the event to the host activity
        mCallback.onArticleSelected(position);
    }

Implement the Interface

In order to receive event callbacks from the fragment, the activity that hosts it must implement the interface defined in the fragment class.

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article
    }
}

Deliver a Message to a Fragment

The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.

For instance, imagine that the activity shown above may contain another fragment that's used to display the item specified by the data returned in the above callback method. In this case, the activity can pass the information received in the callback method to the other fragment that will display the item:

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article

        ArticleFragment articleFrag = (ArticleFragment)
                getSupportFragmentManager().findFragmentById(R.id.article_fragment);

        if (articleFrag != null) {
            // If article frag is available, we're in two-pane layout...

            // Call a method in the ArticleFragment to update its content
            articleFrag.updateArticleView(position);
        } else {
            // Otherwise, we're in the one-pane layout and must swap frags...

            // Create fragment and give it an argument for the selected article
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // Replace whatever is in the fragment_container view with this fragment,
            // and add the transaction to the back stack so the user can navigate back
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }
    }
}

From Official Documentation. Archived version

Upvotes: 4

Shalauddin Ahamad Shuza
Shalauddin Ahamad Shuza

Reputation: 3657

You can use shared ViewModel. Create ViewModel in activity scope and it will be available for activity and all of its fragment.

MyViewModel sharedViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel::class.java)

Then observe your desire data of sharedViewModel. If you change data of sharedViewModel in any fragment or activity it will be changed for all fragment and activity. See below image or read doc.

enter image description here

Upvotes: 7

Ankita
Ankita

Reputation: 1149

To share data between fragments you can use ViewModel.

View model provides a communication layer between different fragments of an activity. To get data on fragment close, you can use onActivityResult also.

For detailed example follow this link- Android: Passing data from child fragment to parent fragment

Upvotes: 2

Related Questions