1

I have a question more simple, but I can't find answers about it on the internet. Here's the deal: I have three fragments and I need to send data of each fragment to a single activity and then to open another activity. I intend to use an interface to do that. So, I need to create three interfaces one to each fragment and implements them on activity? I have three implementations getting data for each activity? Before doing the codes, I need about it. Thanks in advance.

Demo image

Taseer
  • 3,432
  • 3
  • 16
  • 35
  • Beside interface, you could create a singleton data holder class **OR** use a `ViewModel` – Taseer Jun 09 '19 at 17:36
  • @Taseer Ahmad. The viewModel would be impracticable to what I want to do? They are 5 fragments managed for single parent activity on that hosts them. The imagem is above on description. – PauloAndrade Jun 19 '19 at 22:20
  • ViewModel is not an impractical approach, however, if you do not wish to add its dependency and if the data you are sending is small, I would suggest you use interfaces. You don't need to create three different interfaces. How has the answer provided below not helped you? What do you not understand? – Taseer Jun 20 '19 at 06:20
  • @Tasser Ahmad. I can't understand how to get data from three fragments and seding to activity. Where I should do the implementation or intance. Do I have to implement the method of interface class on each fragment and call the object f them in activity or implement the interface in the activity? I want to get theree integer data of each fragment to host container activity. – PauloAndrade Jun 20 '19 at 14:03
  • I could provide you with a sample 'generic' code so you can implement it yourself, but it is in Kotlin – Taseer Jun 20 '19 at 14:05
  • @Tasser Ahmad. There's no problem. If you can send to me. I thank in advance so much. I just need to understand when I have multiple fragments how to follow. Because let me confuse. I know when I have one only fragment I just need to create an interface inside own fragment, and implement it on the parent activity, but related to multiple fragments is complicated. – PauloAndrade Jun 20 '19 at 14:11
  • What kind of data are you sharing to activity? Does each fragment share unique data? – Taseer Jun 20 '19 at 14:24
  • @Tasser Ahmad. they are "Int". Each fragment'll have a result in Integer. No, the fragments don't share unique result. They are three diferents results that should have been sended to parent activity. resultfragment1, resultfragment2 and resultfragment3. – PauloAndrade Jun 20 '19 at 15:17

2 Answers2

2

First, let's create an interface.

interface MyInterface {
     fun onSomethingDone(someData: Int)  //A sample function, you can customize it your needs.
 }

Then

override onAttachFragment in your activity like this. Always remember this rule, never tightly couple a fragment to an activity. So, what you can do is to check the fragment and do relevant operations like this:

class MyActivity : AppCompatActivity() {

    override onAttachFragment(fragment: Fragment) {

           when (fragment) { //A switch statement, checking using instanceOf() in Java.
             is Fragment1 -> fragment.firstFragmentListener = this //Proviving context of your activity to public variable of each fragment.
             is Fragment2 -> fragment.secondFragmentListener = this
             is Fragment3 -> fragment.thirdFragmentListener = this
         }
     }
 }

This will ensure that you are not tightly coupling the fragment like casting it the context of a specific activity while setting up your custom listener.

Lets move to fragments

 class Fragment1 : Fragment() {

     var firstFragmentListener: MyInterface? =  null  //public member, we are accessing it in our activity method, look above! 

      override onCreate() {

          myButton.setOnClickListener {
              firstFragmentListener.onSomethingDone(999) // Just sending random integer as the method parameter.
           }
       }
  }

This one sample fragment class should give you enough idea on how this is being set up. Just the way this fragment class is implemented, you can do the same with Fragment2, and Fragment3.

Back to our activity

But this time, we will implement a listener method.

class MyActivity : AppCompatActivity(), MyInterface {

   override fun onSomethingDone(someData: Int) {
      when (someData) {
         999 -> //Came from first fragment
         1000 -> //Second fragment
         1001 -> //Third fragment
      }
    }

    override onAttachFragment(fragment: Fragment) {

           when (fragment) { //A switch statement, checking using instanceOf() in Java.
             is Fragment1 -> firstFragmentListener = this //Proviving context of your activity to public variable of each fragment.
             is Fragment2 -> secondFragmentListener = this
             is Fragment3 -> thirdFragmentListener = this
         }
     }
 }

This is about it, I will hook up a link to give you a wild idea. Single interface for multiple fragments. While ViewModel is a part of the second generation Android development and offers various advantages not just intercommunication between fragments and an activity.

Taseer
  • 3,432
  • 3
  • 16
  • 35
  • `is Fragment1 -> fragment.firstFragmentListener = this` how to do this in java? should i create a getter method for the listener in Fragment1! – Ibrahim Abousalem Jun 20 '19 at 16:28
  • `if (fragment instanceOf Fragment1)`. You need to use `instanceOf` keyword. Since the listener in `Fragment1` is public, you don't need to create a getter setter since they make sense for private members. – Taseer Jun 20 '19 at 16:38
  • should i override `onDetach` methode and make `firstFragmentListener = null`, or it'll not make any difference. – Ibrahim Abousalem Jun 20 '19 at 16:42
  • 1
    @IbrahimAbousalem No need, since the fragment is tied to your class, everything will be auto cleaned once the activity goes out of scope. Also, these listener is super lightweight that you can just ignore them. You can make them null but don't expect anything good to happen. Please read [this](https://stackoverflow.com/a/449425/9968399) – Taseer Jun 20 '19 at 16:44
  • Thank you so much Taseer Ahmad. In each fragment I declared the object of interface type and overrided "onAttach". In the parent activity I implemented the interface. Puted parameters such as (int, tag) and inside its checked out for "switch case" each tag and I did the operations of storing these datas in local variables of activity. As I needed return values in order to use in other operations , I resolved for each case, storing these datas in local variables of parent activity. Now I'm going to use these values to replace for other fragments. – PauloAndrade Jun 22 '19 at 15:37
1

You could create one seperate interface via New > Java Class and then simply choose Kind > Interface in the dialog. Then you add the methods you need to the Interface and let your Activity implement it. After doing so you go to your Fragments and get an instance of that Interface in the onAttach(Context context) method like this:

    @Override
    public void onAttach(@NonNull Context context)
    {
        Log.d(TAG, "onAttach:true");

        super.onAttach(context);

        if (context instanceof OnFragmentInteractionListener)
        {
            mFragmentInteractionListener = (OnFragmentInteractionListener) context;
        }
        else
        {
            throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
        }
    }

Now you can call the Interfaces methods by saying mFragmentInteractionListener.deleteInternet(true) anywhere in your Fragment class for example.

If you have any further questions, just let me know in the comments.

René Jörg Spies
  • 1,544
  • 1
  • 10
  • 29
  • Oh Thank you René. But I'm a little newbie how about that. I have three fragments: A, B, C. Each fragment have a diferent result: result A, result B and result C. I need these fragments send data to parent activity and depending on the result this activity'll open another fragment D or E. So, That's why I have a question: Do I have to create theree, for example, "mFragmentInteractionListener" to each fragment and implement them in activity? I've read about it a lot, But I can't find anything related to send data for more than one fragment to activity. – PauloAndrade Jun 14 '19 at 12:18
  • Give me a little more information on that one. What information do you need to pass to your underlaying activity from every fragment? – René Jörg Spies Jun 14 '19 at 17:20
  • I need to send the result of three sum integer. Here's the deal: int sum1 (fragment1), int sum2 (fragment2) and int sum3 (fragment 3) to activity. The examples that I find on the internet are using single fragment with an interface inside its. But As you said me, it's better to create interface class separate and getting the result of each. – PauloAndrade Jun 14 '19 at 17:45
  • How does your activity handle the fragment output? Does it need to know from which fragment it came? – René Jörg Spies Jun 14 '19 at 17:58
  • My activity hold 3 fragments inside a container (dinamically). One fragment replace another in the same activity. I need to catch the sum of each and send to parent activity of them – PauloAndrade Jun 14 '19 at 18:48
  • Ok, so you call new fragments from the fragment classes? If that's the case, I suggest you to use the version with a listener for each of your fragments since you need to start new fragments from activity level because fragments are meant to be reusable and that's also the reason why you even need a listener for this. The reason why I suggested the version with only one listener is because e. g. if you need to pass an integer from every fragment to the activity, you would only need one listener class and one method (for all three). But since you want to replace a fragment with another one it's – René Jörg Spies Jun 14 '19 at 19:56
  • Recommended to do that via the listener interface. Now it doesn't matter if you use one standalone interface as your listener or one subinterface for each fragment class – René Jörg Spies Jun 14 '19 at 19:58
  • I'm trying to do that, but as I'm newbie in fragments communications, I can't do it. I've already tried to look for several sites related to that, but it seems like very hard. I updated above what I intend to do in order to clear my target. If you can help me, thanks in advance. – PauloAndrade Jun 19 '19 at 22:16