I've got a pretty complicated layout: a master-detail view, where the detail fragment contains a pager with 3 other fragments in it. I'm getting a bit lost ensuring that each fragment has the correct arguments passed to it, especially since some data is loaded via async tasks in the main detail fragment and is then pushed into subfragments.
Add to all of this that many fragments are displayed in activities on phones, and I've got lots of different ways of loading the same fragments.
What would be a good way of ensuring that all of the arguments I need are set for each fragment, by every activity/fragment that uses them?
I was thinking of adding a static 'build' method to the fragments that would return an instance of the fragment with the arguments bundle correctly populated, but this doesn't really work when data is set following asyncTasks.
Can anyone suggest how I can manage the data flow between my fragments & activities?
Taking the static 'build' idea one step further, you could create POJOs that hold the necessary arguments for a given fragment and add methods that can do the POJO <-> Intent conversions.
The master view could create a POJO, popuplate its fields, convert POJO to Intent and pass the intent to the fragments. The fragments then could build their own POJO from the intent.
Related
I have one Activity and want to share data between that Activity and fragments. I put data in extra while in a fragment and put also other data in it. That way I Have a shared Bundle across my application. I only see examples of passing a Bundle to an Intent but its also possible to change that data while in another fragment. This does not break with the self-containment of fragments. I dont put them in some method in activity because then you will have to cast the activity. Can anybody tell me its right to do? I know about shared pref but I dont want a file based solution. I know about passing parameters with newInStance but I also need to save data back in fragments. passing parameters is only forward not shared.
Passing data from activity/fragment back & forth using Bundles would have some limitations and issues for instance:
To pass a complex object, you'd need to use a serializable marked with a key.
Keeping shared keys in different parts can lead to runtime
errors or data loss if keys are wrong.
Serialized objects are not recommended, but it can be solved with Parcelables. But maintaining that is not that easy for complex objects check here, and you would need to customize that for different types of objects.
Still you don't share data among different fragments but they're just transported; and need to be transported over and over again when you go to a new part of your app.
Not guaranteed to keep the data if the activity is recreated.
Instead of that you'd use ViewModels through MVVM structure where:
Data can be shared on different levels of lifecycle scopes; this means that if the ViewModel is instantiated through ViewModelProvider in activity; then it can be accessed in any part of the activity, or underlying fragments. And if you want to keep only data shared between any fragment and its underlying fragments; you'd bound the ViewModel instantiation to that fragment instead.
ViewModel is instantiated once in the owner, and accessed in the subordinate fragments with no re-instantiation.
If the activity is re-created, it receives the same ViewModel instance that was created by the owner, and the view's data won't be lost.
When the owner activity/fragment is finished, the framework automatically calls the ViewModel's onCleared() method so that it can clean up the resources.
Here is a code lab that you'd check.
I have a view pager that is a fragment. Inside this, I have three fragments each one show a list of items that have the same model but filtered by one state (property in my model), for example like whatsapp that I have one list for all my conversations, other for conversations that I haven't read and finally other for that I've read.
The problem is that I have to refresh all the data when I'm inside the first fragment (all my conversations). So, I've tried to get all my data in the container fragment(view pager) but I cant see my first list with data(all my conversations) because when the container view is created, the first and second fragments is created too.
How can I get the data in the container (view pager) and immediately show the respective list in each child fragment?
The solution is not to store data in any Fragment.
It is a very common use case that if a data is needed in Fragment (or Activity) X, then it will also be needed in Fragment Y. Sharing any state between Fragments is not easy and error prone, therefore I always advice to keep application's data in "application global scope".
What you need is some object, let's call it DataRepository, that lives in the scope of Application object and is injected into all Fragments. Since it lives in Application scope, the data is not tied to any specific Fragment and all Fragments can access and filter the data however you find appropriate.
The most convenient way to define such a "global" object is to use dependency injection framework (e.g. Dagger) and designate DataRepository as scoped injection in ApplicationComponent.
I made several api calls from a model class of an Activity and upon receiving responses from each of them, I need to feed the data to a Fragment one after the other by invoking multiple instances of the same fragment.
Ideally, the next fragment will only be fed with data after the previous Fragment has exited (by response from a listener).
I have looked everywhere and couldn't find a solution to this problem. I have tried using AsyncTask with a CountDownLatch to block the next api response before getting an action response from the initial Fragment but after it only invoked one Fragment (I know how many fragments I should be creating) and back to normal Activity view.
Any thoughts on how to deal with this problem?
There are 2 ways for this
Create a constructor to the fragment where you pass the data when you create instances.
mFragment1 = new xFragment(dataA);
mFragment2 = new xFragment(dataB)
To use Interface and Implementation to pass data from Activity to. Check the link below
https://developer.android.com/training/basics/fragments/communicating.html
I'm developing an android application in which is needed one object which contains an arraylist of objects to be edited.
The idea is each of the objects in the arraylist is to be edited in a different fragment.
The app is using ORM to sore objects in database, so I need each object from this arraylist to be edited in different fragments and when save button is pressed to collect the objects from the fragments, to update the main object and save it.
Now I'm creating the fragments and using setters I'm setting the objects for each fragment in the main activity:
DailyFragment fragment2 = new DailyFragment();
fragment2.setdaySchedule(daySchedule);
fragment2.setmDayIndex(1);
Using this approach in each fragment I have reference to the needed element of the arraylist, so it is not needed anything to be done when the main object is saved.
I need advise if there are better ways this to be achieved?
I would consider moving your data out of the fragments.
Look into using something like dependency injection (dagger) to create places to keep and modify your data.
Ideally your fragments contain little more than what is needed to display information correctly. If you bundle everything into activities/fragments you'll continuously be hampered by the need to communicate between them.
I am working on a Android app which have 5 fragments and some java classes.
I have to be able to read and edit an arraylist containing pojo's from across these fragments and classes. For example updating from the internet and then updating recyclerView in one of the fragments or sorting the objects in a recyclerView in one fragment and have those changes updated in the recyclerView in another fragment.
I have been looking at notifyDatasetChanged, but cannot get it right, when starting an update in the background and then wants it to update onSucceed in the active fragment.
I have been looking on RxJava with the Arraylist as observable, but once again I ran into problems when I wanted to subscribe from multiple fragments.
And of course I did a arraylist in a singleton, but I am pretty sure that is bad coding :-)
I would put the data that is going to be accessed by all of the fragments in a Service. Each Fragment can bind to the service to retrieve a reference to the data and to register a listener (you will have to make a custom one to handle the events that you are interested in) that will tell each Fragment to update its own view. Each Fragment would implement its own Adapter that would wrap the shared data that lives in the Service.