Hi Iam using Event bus to pass data from one fragment to another Fragment
From fragment-1 I am doing as below
#Override
public void onPause() {
bsValues = new BoreShaftValues(strtext, strtextshaft);
bus.post(bsValues);
super.onPause();
}
In Fragment-2 I registered bus in OnActivitycreated
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
bus.register(this);
}
Then I placed OnEvent() method in fragment-2
public void onEvent(BoreShaftValues event){
boregradeselect.setText(event.getBoreData());
shaftgradeselect.setText(event.getShaftData());
}
Below is my BoreshaftVales class
public class BoreShaftValues {
private String boredata;
private String shaftdata;
public BoreShaftValues(String boredata, String shaftdata){
this.boredata = boredata;
this.shaftdata = shaftdata;
}
public String getBoreData(){
return boredata;
}
public String getShaftData(){
return shaftdata;
}
}
But this OnEvent() method is not getting called at all. Am i doing it the rightway?
I typically try to tie EventBus back to the Activity and yet enable it to be loosely coupled. So in the Fragment lifecycle I register EventBus in the onAttach and unregister it in the onDetach methods in the fragment.
Related
I have this issue of sending some data back and forth between a fragment and its container activity, I succeeded in doing it. What puzzles me is sending my data from the fragment to the activity, at first I implemented OnResume(), OnStop() and sent the data through an intent and that created an infinite loop so I removed them. Then I did setRetainInstance(true) and it worked and gave me the wanted behavior.
My Question is How my data are really being sent and where in the fragment lifecycle ?
The Right approach is to use Interfaces. Don't use onStop or setRetainInstance()
See this. It will solve you problem.
Pass data from fragment to actvity
You can also achieve this by using Interface, using an EventBus like LocalBroadcastManager, or starting a new Activity with an Intent and some form of flag passed into its extras Bundle or something else.
Here is an example about using Interface:
1. Add function sendDataToActivity() into the interface (EventListener).
//EventListener.java
public interface EventListener {
public void sendDataToActivity(String data);
}
2. Implement this functions in your MainActivity.
// MainActivity.java
public class MainActivity extends AppCompatActivity implements EventListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void sendDataToActivity(String data) {
Log.i("MainActivity", "sendDataToActivity: " + data);
}
}
3. Create the listener in MyFragment and attach it to the Activity.
4. Finally, call function using listener.sendDataToActivity("Hello World!").
// MyFragment.java
public class MyFragment extends Fragment {
private EventListener listener;
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
if(activity instanceof EventListener) {
listener = (EventListener)activity;
} else {
// Throw an error!
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
// Send data
listener.sendDataToActivity("Hello World!");
return view;
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Hope this will help~
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);
Is there any function that is called when a fragment is killed? Or can an Activity listen for such changes like fragment removal etc?
here are some of fragment life cycle methods names are pretty self describing
you can call your activity's method from those bellow
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onDetach() {
super.onDetach();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onPause() {
super.onPause();
}
ok here is a way to add listener to your activity.
1 create Callback interface like this
public interface CallBack<T> {
void onCall(int key, T body);
}
2 make your activity to implement it e.g.
public class MyActivity extends Activity implements Callback
once you do that you will need to implement onCall method in your activity class
onCall is a method that will be called from fragment
3 in your fragment class ad a member variable
private Callback<TypeYouWant> callback;
4 create a setter for callback
public void setCallBack(Callback c){
this.callback = c;
}
5 go to you activity and setCallback, since your activity knows about your fragment therefore you have reference to it. at least you can get it with getFragmentManager().findFragmentById() . in activity's onCreate method add this
myFragment.setCallback(this) //note you can pass **this** because your activity implements `Callback` interface
6 last step , in your fragment's onDetach add
#Override
public void onDetach() {
super.onDetach();
if(callback !=null){
callback.call(some key, some T type value);
}
}
so that's it whenever onDetach called in fragment your activity will get callback