0

I'm creating an app, and I have a doubt on how to communicate between fragments, I know I must communicate to the parent activity and etcetera my question is more best practice oriented. My app consists of a MainActivity with a navigation drawer which depending on the selection calls a fragment and puts it on the main screen. I have 2 fragments which via a button need to call another fragment (I can convert it to an activity with no problem) that opens the camera to scan a barcode (BarScanFragment) (https://github.com/dm77/barcodescanner).

My question is it possible to know which fragment called the BarScanFragment so I can send the argument to the correct fragment, and how do I achieve it.

BarScanFragment.java

public class BarScanFragment extends Fragment implements  ZXingScannerView.ResultHandler{
    private ZXingScannerView mScannerView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mScannerView = new ZXingScannerView(getActivity());
        return mScannerView;
    }

    @Override
    public void onResume() {
        super.onResume();
        mScannerView.setResultHandler(this);
        mScannerView.startCamera();
    }

    @Override
    public void onPause() {
        super.onPause();
        mScannerView.stopCamera();

    }

    @Override
    public void handleResult(Result result) {
        Log.i("TAG", result.getText());
        Bundle args = new Bundle();
        args.putString("barcodeScan", result.getText());
    }

FragmentA.java

...... ......

barcodeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Fragment content = new BarScanFragment();
                FragmentManager fragmentManager = getFragmentManager();
                fragmentManager.beginTransaction()
                        .replace(R.id.flFragmentContainer, content).addToBackStack("TRADEIN")
                        .commit();
                /*Intent intent = new Intent(rootView.getContext(), BarcodeScannerActivity.class);
                startActivity(intent);*/
            }
        });

Fragment b.java

.....
.....
 barcodeButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Fragment content = new BarScanFragment();
                    FragmentManager fragmentManager = getFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.flFragmentContainer, content).addToBackStack("INFOPRODUCT")
                            .commit();
                    /*Intent intent = new Intent(rootView.getContext(), BarcodeScannerActivity.class);
                    startActivity(intent);*/
                }
            });
user2844810
  • 985
  • 7
  • 11

3 Answers3

1

Take a look on setTargetFragment and getTargetFragment. It's the easiest way to communicate back and forth between fragment. Here there is a little example https://github.com/alexfu/TargetFragmentExample

Dekra
  • 554
  • 5
  • 15
  • This was easier to implement than the callbacks, are there any performance pros or cons within your answer and Oleg Osipenko's answer – user2844810 Jan 23 '15 at 21:54
  • I'll accept this answer since it was the easier to implement, Oleg's answer also worked great. Thanks. – user2844810 Jan 24 '15 at 00:48
  • Oleg Osipenko's answer is good as well. Therefore, Fragment is not always related with single Activity; so,for every Activity,which uses a Fragment, you have to implements the two interfaces. Instead, set/getTargetFragment methods belong to the Android Framework and need to be used for this approach. With them you don't have to reinvent the wheel. – Dekra Jan 24 '15 at 10:51
0

Declare callbacks in your activity and call methods from another fragment using these callbacks

public interface Callback1 {
    void callbackMethod1();
}

public interface Callback2 {
    void callbackMethod2();
}

public class Activity extends ActionBarActivity implements Callback1, Callback2 {

    Fragment1 mFragment1;
    Fragment2 mFragment2;

    @Override
    public void callbackMethod1() {
        mFragment2.method2();
    }

    @Override
    public void callbackMethod2() {
        mFragment1.method1();
    }
}

public class Fragment1 extends Fragment {
    Callback1 callback;

    @Override
    public void onAttach(android.app.Activity activity) {
        super.onAttach(activity);
        callback = (Callback1) getActivity();
    }

    void callMethodOfFragment1() {
        callback.callbackMethod1();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callback = null;
    }

    public void method1() {
        do_sth_in_fr2();
    }
}

public class Fragment2 extends Fragment {
    Callback2 callback;

    @Override
    public void onAttach(android.app.Activity activity) {
        super.onAttach(activity);
        callback = (Callback2) getActivity();
    }

    void callMethodOfFragment2() {
        callback.callbackMethod2();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callback = null;
    }

    public void method2() {
        do_sth_in_fr1();
    }
}
Oleg Osipenko
  • 2,409
  • 1
  • 20
  • 28
  • http://stackoverflow.com/questions/26129626/how-to-run-a-fragment-from-another-fragment/26130044#26130044 – Kristy Welsh Jan 23 '15 at 19:29
  • if you look closely at your example and at my code you'll see that both activities implements an interface and fragments call method of this interface to communicate from fragment to activity. So that's the difference and that's the reason do downvote my answer? – Oleg Osipenko Jan 23 '15 at 19:35
  • @OlegOsipenko hi could you please elaborate more especially on how does the activity has to respond since mFragment2.method doesn't tell me anything, I don't get how to know which fragment to respond, since 2 fragments can call the same scan fragment and everything is on the same fragment container. – user2844810 Jan 23 '15 at 20:03
  • I've just edited my answer so there is a communication between two fragments via activity using interfaces as Kristy Welsh advised – Oleg Osipenko Jan 23 '15 at 20:58
  • @OlegOsipenko Your answer worked pretty well, I'm upvoting it, I've tried Dekra's answer and it also works and it's a little easier to implement, are there any performance pros or cons within the 2 methods yours and Dekra's? – user2844810 Jan 23 '15 at 21:53
  • in case of your particular problem it's easy to use Dekra's answer – Oleg Osipenko Jan 23 '15 at 22:48
0

You can add a parameter to the BarScanFragment's constructor:

public BarScanFragment(int creatorFragment) {
    // Do something with creatorFragment
}

Save "creatorFragment" values in your activity:

public static final int FRAGMENT_1 = 0;
public static final int FRAGMENT_2 = 1;

Then in your button listeners create the BarScanFragment with a specific value:

Fragment content = new BarScanFragment(MainActivity.FRAGMENT_1);

or

Fragment content = new BarScanFragment(MainActivity.FRAGMENT_2);
Simas
  • 43,548
  • 10
  • 88
  • 116