I've searched a lot on how to communicate between fragments using SlidingTabLayout but haven't really got a good answer. I know using ActionBar but I wanted the new way that is for android lollipop using SlidingTabLayout. I tried this-> http://android-er.blogspot.in/2012/06/communication-between-fragments-in.html but I wanted material design. I referred this link http://www.android4devs.com/2015/01/how-to-make-material-design-sliding-tabs.html for making material design sliding tabs. Now I wanted to know how to communicate between the sliding tabs. I've tried a lot but couldn't find the answer I was looking for. Any help would really appreciated.
-
Basically it's a communication with fragments right ? then try search about fragment communication. http://developer.android.com/training/basics/fragments/communicating.html – Anoop M Maddasseri Jul 23 '15 at 13:00
-
Yes it is that. The link doesn't really explain for swipe tabs. I tried that already with no success :( – MVK059 Jul 23 '15 at 13:04
-
http://developer.android.com/training/implementing-navigation/lateral.html – Anoop M Maddasseri Jul 23 '15 at 13:08
-
Is each of your tab a new fragment? – milez Jul 23 '15 at 13:11
-
Yes it is. There are two tabs – MVK059 Jul 23 '15 at 13:17
3 Answers
The cleanest way is to define an interface that the Activity
that contains the Fragment
s will implement. This is how I recently solved this:
First define the interface in it's own file, because it has to be visible to other classes.
public interface FragmentCommunication
{
public void printMessage(String message);
//....
}
In your Activity
you need to implement this interface
public class MainActivity extends ActionBarActivity implements FragmentCommunication
{
//....
public void printMessage(String message)
{
System.out.println(message);
}
}
Finally in your Fragment
s you can get the hosting Activity
with getActivity()
and to use the communication methods just cast the activity into the implemented communication interface like so:
((FragmentCommunication) getActivity()).printMessage("Hello from Fragment!");
EDIT: To further pass the message to other Fragment
s do this: since your tabs all extend Fragment
it is the best to create another interface
public Interface ReceiverInterface
{
public void receiveMessage(String str);
}
Then implement this in your tabs
public class Tab1 extends Fragment implements ReceiverInterface
{
// .... code .....
public void receiveString(String str)
{
//use str
}
}
To further send this message to other Fragments it is required that the activity sees them. For example now modify the printMessage()
that Activity
implements to this
public void printMessage(String message)
{
System.out.println(message);
//Send the message that came from one fragment to another
if (tabFragment1 instanceof ReceiverInterface){
((ReceiverInterface) tabFragment1).receiveMessage(message);
}
}
-
I want to send a string from one fragment to another. So when I click on a button in fragment A it should pass a bundle or a string to fragment B. How do you reckon I do that – MVK059 Jul 23 '15 at 13:30
-
Then it is required that activity has access to both fragments. does it? You send the string from one fragment via interface, and place it to fragment from activity in the interface method. The fragments need a method for receiving the message too, but the activity sees all the methods your fragments have as long as they are public, so no need for an interface. – milez Jul 23 '15 at 13:32
-
Yes, the activity has access to both the fragments. I send string from fragment A but the problem I was facing was fragment B wasn't getting what was sent. How to implement a method for receiving the messages in fragment B – MVK059 Jul 23 '15 at 13:35
-
-
Can you at least do it when you are can. It'd really be a great help. I'm stuck on this problem for over a week. It'd be really helpful. – MVK059 Jul 23 '15 at 13:46
-
And where do you call the method receiveString. And why can't I just from the MainActivity containing the fragments call one of the fragments and pass data? Like create an instance of one fragment and pass the data – MVK059 Jul 23 '15 at 13:56
-
I hope my edit resolves this issue. I understood that your Activity has acces to instances of the fragments.. – milez Jul 23 '15 at 14:06
-
I looked more carefully at the code you used to create the tabs. It seems that in the ViewPagerAdapters getItem() method a new object of each tab is created when the view changes. So this means that if you are on tab2 and send a message to tab1, then try to go back to tab1, a _new_ Tab1 instance is created, while the old tab1 received the message. Do you see the problem? You would have to create the fragments in the Adapter, save them there, then in getItem return an existing object, not create a new one. – milez Jul 23 '15 at 14:15
-
Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/84085/discussion-between-mvk059-and-milez). – MVK059 Jul 23 '15 at 14:16
-
@MVK059, I am familiar with Google's SlidingTabLayout project. Is this the one you're using? I am in the middle of implementing an interface for communication between fragments. Are you interested? will it be helpful? – The Original Android Jul 24 '15 at 00:29
-
Brother, in addition to making me spend the day, you still made me understand how to implement Interface - which I had already given up on another occasion because I didn't understand. Thanks a lot! you are the IT guy. Hahaha – Vicente Domingos May 11 '21 at 22:27
When you slide tabs (ViewPager
), you can either work with the same Fragment
or use different Fragments
.
As you previously mentioned, you tried this, so I'm going with different Fragments
.
What you are going to do is basically use EventBus
: https://github.com/greenrobot/EventBus.
Add it to your build.gradle
dependencies located inside app
folder.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'de.greenrobot:eventbus:2.4.0'
}
You could also achieve it by using Intents
.
1 - Create a class to represent event when your text changes:
public class TextChangedEvent {
public String newText;
public TextChangedEvent(String newText) {
this.newText = newText;
}
}
2 - Fragment A:
//when text changes
EventBus bus = EventBus.getDefault();
bus.post(new TextChangedEvent(newText));
3 - Fragment B:
EventBus bus = EventBus.getDefault();
//Register to EventBus
@Override
public void onCreate(SavedInstanceState savedState) {
bus.register(this);
}
//catch Event from fragment A
public void onEvent(TextChangedEvent event) {
yourTextView.setText(event.newText);
}
-
When I add compile 'de.greenrobot:eventbus:2.4.0' this to my gradle file, it says it failed to resolve – MVK059 Jul 23 '15 at 13:41
-
Are you adding on the right place? It should be inside your `app` build.gradle file. Check this if my edit doesn't help: http://stackoverflow.com/questions/28493470/gradle-failed-to-resolve-library-in-android-studio – Machado Jul 23 '15 at 13:47
-
-
You just saved the day! Is it possible to do the same thing with LiveData ? – Karan Khurana Feb 11 '20 at 11:57
Use EventBus GitHub library. This is currently the simplest and most convenient way. https://github.com/greenrobot/EventBus

- 1,160
- 3
- 14
- 26