Search code examples
androidandroid-fragmentsandroid-lifecyclefragment-lifecycle

Communication between two fragments with interface


My app have one activity A and two fragments F1 and F2.

One clicking button in F1, the F1 is replaced by F2. I want to transfer data in F1 to F2. For that I implemented the interface in F1 and override its method in A.

But when sending the data from A to F2, my reference(sFragment in code A) to the F2 remains null,due to which data is not sent to F2. I am getting reference to the F2 using TAG provided while replacing F1 by F2.

Does it have something to do with the lifecycle like when I am trying to get reference to the F2 it hasn't yet created?

F1

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

    View v = inflater.inflate(R.layout.form_fragment1,container,false); 
    nextB = (Button) v.findViewById(R.id.f1Next);
    nextB.setOnClickListener(this);
    return v;
}

@Override
public void onClick(View view) {
    switch (view.getId()){

        case R.id.f1Next:
            SFragment fragment = new SFragment();
            FragmentManager mManager = getFragmentManager();
            FragmentTransaction mTransaction = mManager.beginTransaction();
            mTransaction.replace(R.id.fragment_container,fragment,"SecondF"); // SecondF
            mTransaction.addToBackStack(null);  // this is required to move to the previous fragment
            mTransaction.commit();
            commListener.PlaceName(data1,data2);  //passing value to activity
            break;

    }

}
interface CommBridge{

    void PlaceName(String data1,String data2);
}

@Override
public void onAttach(Context context){
    super.onAttach(context);
    if (context instanceof CommBridge){
        commListener= (CommBridge) context;
    }
}

}

A

 @Override
public void PlaceName(String data1, String data2) {
    SFragment sFragment=(SFragment) getFragmentManager().findFragmentByTag("SecondF");
    if (sFragment != null && sFragment.isInLayout()){
        Log.d("STATE","1");
        sFragment.setPlace(data1,data2);
    }else{
        Log.d("STATE","2");  // this is always  the case
    }

F2

public class SFragment extends Fragment {
String Place2,Place1;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    View v = inflater.inflate(R.layout.form_fragment2,container,false);
    return v;
}

void setPlace(String data1, String data2){
    place1 = data1;
    place2 =  data2;

}
}

Solution

  • I would recommend putting the code for replacing the fragment in your Activity and put the values which should be passed to SFragment() in its arguments directly:

    SFragment newFragment = new SFragment();
    Bundle args = new Bundle();
    args.putString("place1", data1);
    args.putString("place2", data1);
    newFragment.setArguments(args);
    

    You could get them in SFragment#onCreateView()

    String place1 = getArguments().getString("place1");
    

    Also have a look here: https://developer.android.com/training/basics/fragments/communicating.html