Babs
Babs

Reputation: 343

Fragment to Fragment communication fails using LocalBroadcastManager

I am having a problem transfering data from one fragment to another using LocalbroadcastManager.

FragmentA has editText and onclick on it will launch FragmentB. FragmentB has a list of items and onclick on each item I want to pass the data to FragmentA.

Here is my implementation.

public class FragmentA extends Fragment {
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String highSchoolName = intent.getStringExtra("HighSchoolName");
    }
};

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(mMessageReceiver, new IntentFilter("HighSchoolEvent"));
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mMessageReceiver);
}

Below is Fragment B where broadcast message is sent from.

public class FragmentB extends Fragment {

    mHighSchoolListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            HighSchool highSchoolItem = mHighSchoolAdapter.getItem(position);
            sendHighSchoolItemToSignupForm(highSchoolItem);
        }
    });

    private void sendHighSchoolItemToSignupForm(HighSchool highSchoolItem) {
        Intent intent = new Intent("HighSchoolEvent");
        intent.putExtra("HighSchoolName", highSchoolItem.getName());
        LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
        getActivity().onBackPressed();
    }
}

Debug / Logging never hits the onReceive message of Broadcast receiver. Is there anything missing? Appreciate any suggestions.

Upvotes: 0

Views: 469

Answers (3)

Mallikarjuna
Mallikarjuna

Reputation: 883

  1. Define InterFace In Fragment B

    To allow a Fragment to communicate up to its Activity, 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.

    UpdateFragmentA update;
    public interface  UpdateFragmentA {
       
        public void update_fragment(String data);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            update= (UpdateFragmentA ) getActivity();
        }catch (Exception e)
        {
            e.printStackTrace();
        }


    }



// set setOnItemClickListener for List View
listview.setOnItemClickListener(new OnItemClickListener()
{
    @Override 
    public void onItemClick(AdapterView<?> arg0, View arg1,int position, long arg3)
    { 
       update.update_fragment(items[position]);
    }
});

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 FragmentB.UpdateFragmentA{
        ...

        public void update_fragment(String data) {
            // The user selected the Item 

            // send that data to fragment A
            a.recieve(data);  //a is FragmentA reference a=new FragmentA();
        }
    }

The host activity can deliver messages to a fragment by capturing the Fragment instance

In FragmentA Define Method recieve(String s);

   public class FragmentA extends Fragment {
   ....
   ...
   
   public void recieve(String s)
    {
      //You get Selected Item From FragmentB through Activity
            // Do something here to display that

        if(!s.isEmpty())
        {
          textview.setText(s);
        }

    }
    
 }

enter image description here

Upvotes: 0

Chintan Soni
Chintan Soni

Reputation: 25267

If "launch" means you are replacing Fragment A with Fragment B, then you are going wrong..

You should add Fragment B to backstack

FragmentTransaction#addToBackStack(String fragmentName);

and you should do

FragmentTransaction#add()

instead of

FragmentTransaction#replace()

Add: will add another Fragment View to container

Replace: will replace all the contents of a container with another Fragment

I am sure you are replacing Fragment A with Fragment B and in that case your Fragment A will get destroyed and Fragment B will be loaded, you wont be able to listen to updates anymore in Fragment A

Upvotes: 2

Babs
Babs

Reputation: 343

As J Ramesh suggested, by changing the fragment transaction type from replace to add, fixed the issue.

Here is the fragment transaction.

    FragmentManager fm = getFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.add(android.R.id.content, new FragmentA())
            .addToBackStack(null).commit();

Upvotes: 0

Related Questions