Pass data from fragments to activity when changing fragment - android

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.

Related

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.

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.

Send message to TabHost's Fragment from Activity

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();
}

DialogFragment in Fragment and callbacks

I have read a lot of documents about how to use fragments but I have one more doubt.
I have one activity that controls 3 fragments, now in one of this fragment I call a DialogFragment and following the google's tutorial I defined an interface to the activity for callbacks. All it's works properly but is this the only way to pass data to the fragment that fired the Dialog? I think that it would be more convenient passing data directly to the fragment instead of passing from the activity. is there any method to do this?
Thank you in advance.

Reuse fragment structure and passing complex arguments

I have implemented a DialogFragment class which shows a dialog and call a custom listener when its button is pressed.
Since I want to reuse this class in many projects I need to pass the listener when I create the fragment. However I don't know how I could do it.
I know I should not pass the listener in the constructor because Android could call the default constructor if it has to recreate the fragment and I cannot pass the listener via Bundle arguments because Bundle does not support it.
The unique solution I found is make the activity implement the custom listener and check it in onAttach method. The problem is that this way would limit the implementing classes to the owner activity and maybe it does not fit to the application.
Does you find a better solution?
Thanks!
You normally have a static newInstance() method to create your fragment and pass in any values your fragment might need. That's the method to pass your listener to.
Have a look here where a newInstance() method is also used as an example:
http://developer.android.com/reference/android/app/Fragment.html

Categories

Resources