I am using EventBus to send the long value from a fragment to another fragment. I use the following code to do that. But for me, it doesn't work. What did I do wrong?
This is the fragment where I save the data:
#OnClick(R.id.buttonFinishMeeting)
public void onClickButton() {
startActivity(RoutePlanCompleteActivity.newIntent(getContext(), routePlan));
EventBus.getDefault().post(new Long(spentTime));
}
Then the fragment I want to send my data:
#Subscribe
public void onEvent(Long time) {
spentTime = time;
}
#Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
#Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
}
Replace your subscribe method like this :-
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
---
};
This code has been taken from the official documentation of Eventbus from here. If you have any more trouble, visit this link https://github.com/greenrobot/EventBus
Related
I'm using EventBus 3 to send data between Fragments. I have sent data from Fragment A with EventBus.getDefault.post(etc) and successfully receiving data in Fragment B.
Now when I try to get the same data of Fragment A in Fragment C. Nothing is displaying in Fragment C. No error. May be the subscriber not working. Please guide me how I can get the same data from Fragment A to Fragment B and C with EventBus.
Thanks
you can try this way add dependency inside your build gradle file.
compile 'org.greenrobot:eventbus:3.1.1'
in fragment A override methods like this.send data like this call in your
method from where you want to send data.
EventBus.getDefault().post(new String("Notification"));
#Override
public void onStart() {
super.onStart();
getFriendFromServer();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void toChangeSearchFocus(String event) {
}
in fragment B
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void toChangeSearchFocus(String event) {
// here you will get your data.
}
I have an Activity which has a Save details button and a Viewpager which contains 4 fragments. The Fragments contains User details form. Once the Save button is clicked I need to get the data from all fragments and save the details. How to get the data entered by the user in all 4 fragments when Save button is clicked in the activity?
I just worked on an app that had the same use case. In addition, I had to save the data on a back navigation as well. The problem was a bit more difficult that I though it should have been. The problems came from the fact that not all the fragments in the ViewPager are guaranteed to be alive. They either may not have been started yet, or destroyed when the user paged off of them.
To solve the problem, I took inspiration from this blog post about handing back-press events. I had to modify it a bit to allow for any fragments that may be running and not just one.
public abstract class BackHandledFragment extends Fragment {
protected BackHandlerInterface backHandlerInterface;
public abstract String getTagText();
public abstract boolean onBackPressed();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandlerInterface)) {
throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
} else {
backHandlerInterface = (BackHandlerInterface) getActivity();
}
}
#Override
public void onResume() {
super.onResume();
backHandlerInterface.addRunningFragment(this);
}
#Override
public void onPause() {
super.onPause();
backHandlerInterface.removeRunningFragment(this);
}
public interface BackHandlerInterface {
public void addRunningFragment(BackHandledFragment backHandledFragment);
public void removeRunningFragment(BackHandledFragment backHandledFragment);
}
}
The Activity implements the interface and tracks the active fragments:
public class EditActivity implements BackHandledFragment.BackHandlerInterface
{
private List<BackHandledFragment> listActiveFragments = new ArrayList<>
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Notify each active fragment that the back was pressed, this will allow
// them to save any data.
for (BackHandledFragment bf : listActiveFragments) {
bf.onBackPressed();
}
}
#Override
public void addRunningFragment(BackHandledFragment backHandledFragment) {
listActiveFragments.add(backHandledFragment);
}
#Override
public void removeRunningFragment(BackHandledFragment backHandledFragment) {
listActiveFragments.remove(backHandledFragment);
}();
}
Each fragment must extend BackHandledFragment:
public class DetailNetworkFragment extends BackHandledFragment {
#Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
saveDataFields();
}
#Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
#Override
public String getTagText() {
return TAG;
}
#Override
public boolean onBackPressed() {
saveDataFields();
return false;
}
}
The saveDataFields() is not too interesting. It just copies the data out of the UI views and saves them back to an object in the Activity.
after define event class and post event on Activity onBackPressed() i cant get event on fragment, some my activities opening above this fragment which that is child of MainActivity. i want to get some events that post from other opening activitis, but my code doesnt get this event on Fragment, but i can post event from Activity onBackPressed()
SignalActivityMarketDetailStateEvents class:
public class SignalActivityMarketDetailStateEvents {
private boolean activityMarketDetailState;
public SignalActivityMarketDetailStateEvents(boolean activityMarketDetailState) {
this.activityMarketDetailState = activityMarketDetailState;
}
public boolean isActivityMarketDetailState() {
return activityMarketDetailState;
}
}
ActivitySecond :
#Override
public void onBackPressed() {
EventBus.getDefault().post(new SignalActivityMarketDetailStateEvents(true));
}
Fragment to get event:
#Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(SignalActivityMarketDetailStateEvents event) {
Log.e("EventBus ","Received");
}
#Override
public void onStart() {
EventBus.getDefault().register(this);
super.onStart();
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
#Override
public void onResume() {
EventBus.getDefault().register(this);
super.onResume();
}
in my Fragment this line doesnt work after post event:
Log.e("EventBus ","Received");
You are not mindful of the life cycle's of those activities. You could use the sticky events (postSticky) . Or update the state in some singleton and read that in onResume.
Problem: I am using EventBus by greenrobot to pass some events.
It is working for me unfortunately for the scenario of passing data between two fragments it does not. So the event does not get fired.
Question: Do I misunderstand the concept? Or is there a mistake in my code?
Note: Both Fragments exist at the time of sending the event. One fragment is the parent and the other one the child to display details.
detail fragment:
public class DetailFragment extends Fragment {
(...)
refreshButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EventBus.getDefault().post(new IntentRefresh());
}
});
(...)
}
EventBus class:
public class IntentRefresh {
public IntentRefresh (){}
public void refreshParent() {
}
}
parent fragment:
public class ParentFragment extends Fragment {
(...)
#Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
}
#Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void updateList(IntentRefresh intentRefresh) {
Toast.makeText(getActivity(), "LUEEEEPT", Toast.LENGTH_SHORT).show();
}
(...)
}
The Fragment lifecycle is quite a bit more complicated than the Activity lifecycle. I would guess that your onResume() isn't being called how you think it is. I would recommend moving your registering and un registering to the onAttach() and onDetach() methods.
I use #CaseyB's answer. its working for me perfectly.Like below
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
}
#Override
public void onDetach() {
super.onDetach();
EventBus.getDefault().unregister(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(CallbackModel event) {
}
This is my first activity where Im making a post call. The bus provider is the default one in the otto sample app.
void openNextActivity()
{
manager.bus.post("Hi");
// Intent to my next Activity
}
This is my fragment in another activity where im subscribing for the data. The bus received is the same, however the subscribe method is not being called.
public class ProductListFragment extends BaseFragment {
String LOG_TAG = ProductListFragment.class.getCanonicalName();
public static ProductListFragment newInstance() {
ProductListFragment fragment = new ProductListFragment();
return fragment;
}
public ProductListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().invalidateOptionsMenu();
}
#Override
public void onResume() {
super.onResume();
BusProvider.getInstance().register(this);
}
#Override
public void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe public void onPostRecived(String s) {
Log.d(LOG_TAG, s);
}
}
There are no errors on anything being received, however if I put a button onclick on the fragment and post some content from there, the subscribe method is being called. For eg.
#OnClick(R.id.makePostCall) void call() {
BusProvider.getInstance().post("Hi");
}
I'm getting the appropriate log on this call. Any idea where the code is going wrong?
it seems you subscribe your second activity's fragment after sending stuff to event bus. Consider changing your logic
u send msg before intent;the BusProvider id registered after intent;
just try:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
BusProvider.getInstance().post("Hi");
}
},3000);