Send message to TabHost's Fragment from Activity - android

I have an Activity which contains a Fragment in it. The Fragment contains a TabHost which contains several other Fragments. I need to send a message from Activity to one of TabHosts Fragment, what is the best way to do that?

You can the Observer-pattern implement an Observer interface in your activity, then you can register your fragment as an Observable. Now if you want to sent data to the activity you can use notifyObserver(object dataYouWantToSend) and call hasChanged().
This should be recognized by your activity where the interface method update will receive the data.
I recommend to create a custom observable object there you can override the notifyChange method and directly add the hasChanged() method. The overwritten method would look like this.
notifyChange(Object data) {
super.notifyObservers(data);
setChanged();
}

Related

How to make callBack response from one fragment to another fragment?

Sir/Madam,
I want to make a callback result to one fragment to another fragment using android JAVA.
I try-out to find the issue but non of the solution found.
If i using interface it send callback response to Activity, which i didn't want.
thank you!
You have many options to do so:
Shared ViewModel (Recommended) (https://medium.com/#abhilashmyworld/communicate-between-fragments-using-viewmodel-e83344e9df53)
EventBus
Through the Hosting activity (calling method on fragment object)
Passing objects
Broadcast (too old school)

Better way to pass data between Fragments Navigation Component?

Passing data between Fragments in Navigation Component is easy. Say going from A to B you just set arguments with SafeArgs and you are done.
But, it gets tricky when passing data from B back to A.
According to documentation, we can use SharedViewModel which is works well. But I am looking for better way of passing data back to A from B.
The problem of using SharedViewModel is, you have to create SharedViewModel for every fragment pair that you need to pass data.
Any suggestions? If any annotation-processing method you can think about, you are more than welcome to recommend.
If you do not want to use SharedViewModel way, you can follow the next approach:
1- Define a delegate for your Details Fragment. (This delegate have to implement Serializable or Parcelable:
interface DetailsFragmentDelegate: Serializable {
fun onSomething1(someData1: SomeData1)
fun onSomething2(someData2: SomeData2)
}
2- Add the delegate to your Details Fragment arguments in nav_graph.xml
3- Pass the delegate to your Details Fragment when navigating to its destination by your Base Fragment:
findNavController().navigate(
BaseFragmentDirections.actionBaseFragmentToDetailsFragment(
object: DetailsFragmentDelegate {
// override delegate methods
}
)
)
4- Get the delegate argument in Details Fragment and pass the data back wherever you need:
....
delegate.onSomething1(data1)
....
delegate.onSomething2(data2)
....
I am not sure whether there is a better way or not, but it's working...
You don't need to create a ViewModel per Fragment pair. What I am doing is creating a ViewModel per Fragment. Each ViewModel would have a map[Class[Fragment], Any] named mailBox.
Each Fragment will define a FragmentResult type which is different per Fragment class.
In the child Fragment onBackPressedHandler, before pop-up, fetch the parent ViewModel from the Activity and put your result in the mailBox for your class. You will need a ViewModel class for that. See below.
The parent Fragment needs to pass it's ViewModel.class to the child Fragment, before launching it.
When the Parent Fragment is re-started after popping up the child from the stack. Get the mailBox map from it's ViewModel, check if there is a key with value from the expected FragmentChild::class. If so, then cast to the desired type.
The parent Fragment ViewModel needs to save who was the last child it launched.
I am using an callback interface for this. So i have created an interface with some methods. I implemented that interface 'A' and then call if from 'B'. Very easy and works great.

Pass data from fragments to activity when changing fragment

I'm needing a way to pass data from multiple fragments to an activity. This data can only be sent to the activity when I change the fragment tab.
To pass the data I am using the interface method, but I do not know in which function of the class fragment I can put the method that will take the text of the EditText and send to the activity through the interface.
Is it important to pass the data only when the fragment changes? If not, you could add a callback to the edit text that calls the interface method your activity implements. This answer has some good examples on how to do that.

What is difference in 2 ways transfer data to fragment from activity using getArgument() and getActivity.getXXX()

I wonder the difference between two ways of transfering data from activity to fragment.
One is using getArgument() and setArgument(). I can transfer data using these methods at Fragment's contruction time.
Another is using getActivity() method. Like this way
((HostActivity)getActivity()).getXXX()
After declaring getter method of data Fragment may use, call this method in fragment through getActivity() and Type casting.
I think second one is easier and convenient. Because get/setArgument() can be called only Fragment's contruction time.
So, How to apply these 2 way to sending and getting data between Activity and Fragment?
A Fragment represents a behavior or a portion of user interface in an
Activity. You can combine multiple fragments in a single activity to
build a multi-pane UI and reuse a fragment in multiple activities.
Because fragment can reuse in multiple activity, if you use getActivity() with type casting, you must check instanceOf activity before call method. And each of activity use that fragment, you must implement method getXXX().
Use newInstance method in fragment, you only pass require parameter for it.
If you create fragment for individual activity, you can apply 2 ways transfer data.
The fragment has an independent lifecycle from activity with specific threads, functions and handlers. So you can use getters/setters Activity variables like a global variables and bundle data (arguments) to independent fragment variables.

Populating fragment fields from activity

I have a ViewPager of 3 fragments. All 3 fragments are of the same type, with identical layouts, but they are to hold different (text) information. I am trying to create my activity, where I create the fragments and prepare the text data that I will populate my fragments with. However, I can't seem to work with the fragments from within my activity. All the activity's lifecycle methods are executed before the fragment lifecycle methods. So if I try to update a textview in a fragment from within my activity, it won't work, because the textview is null in the fragment.
I'm going to need to make periodic updates to the fragments, so passing the data as a bundle is not an option. Plus, since I'm passing lots of text, I'm using a StringBuilder object, which is not something I can pass in a bundle (unless I make it Parcelable, which I don't want)
I think I could run a method from within my fragment class that would execute during fragment creation, but that means all 3 fragments would run this method. That's not really the level of control I'm looking for.
Is there a neat way to make this work?
Thanks
Keep references to your fragments, and let them all implement an interface with a common update-method. As an example, let's make it super clear and call the interface Updatable with one method called 'update':
public interface Updatable {
public void update(String text);
}
Now, in your Activity's onCreate, save references to your Updatables there (i.e. when you lookup or instantiate your Fragments).
It should now be trivial to update your Fragments when necessary from the Activity. Needless to say, the fragment implementation of the update code needs to do the actual update of the TextView(s).
If the update implementation is exactly the same for all your Fragments, your could save some lines of code and make a base class which implements Updatable and extends Fragment.
you might able to populating fragment fields during onActivityCreated(Bundle savedInstanceState).
Refer to this site for more information about fragments' life cycle:
http://developer.android.com/guide/components/fragments.html
You should consider using Observer pattern... there is a really great implementation which you can include as gradle dependency called EventBus:
https://github.com/greenrobot/EventBus
You can use Otto Bus to send data to your fragments from your activity.
http://square.github.io/otto/
Create a new bus in you application class
Bus bus = new Bus();
Create an event that contains your data which you'll pass to fragments.
bus.post(new MyDataEvent(data));
Register your fragment in your fragment's onResume() (Do not forget to unregister in your fragment's onPause())
bus.register(this);
And get data with subscribe in your fragment
#Subscribe
public void onDataReceived(MyDataEvent event) {
// TODO Do what ever you want
}
I hope this'll help you.

Categories

Resources