Fragment doesn't refresh - android

I have a Fragment that shows some data saved in android Preference.
when these data changes due to various operations of the app, I want to update the fragment with the new data.
I have tried to use
myFragmentTransaction.notifyAll();
But unfortunately doesn't work and the fragment is updated only when I reopen my whole Activity
Houw could I refresh the Fragment on data changes?

notifyAll pertains to threading. Completely unrelated to what you are doing. Instead of trying to tell each fragment to redraw themselves have you tried OnSharedPreferenceChangeListener. Each fragment should listen to changes in the information they care for.

Related

Saving data to sqlite database and updating recycler list adapter

I'm a newbie to android app dev and I have one little problem. I'm developing a note app with a single activity(MainActivity) which has a NavHost and host three fragments(NewNoteFragment, NoteListFragment and NoteUpdateFragment). The note details are stored in a sqlite database.
Whenever user creates new note or update the existing note, the changes can only be stored to the database in NewNoteFragment or NoteUpdateFragment's onPause override i.e when the user navigates from the said fragments to the NoteListFragment. Although the changes were saved but the recyclerView in the NoteListFragment doesn't update immediately until i kinda navigate away from the NoteListFragment to other fragment.
When I check the logcat i noticed the onResume override(which is where I called my adapter.notifydatasetchanged() method) in my NoteListFragment is called before onPause override of the replaced fragments.
Is there a way to change the fragments navigating behaviour where onpause is called before the onresume? Or any better way to achieve my said aim.
You cannot set onPause to be called before. Since you are using fragments try to update the recyclerView onViewCreated() function of Fragment.
You cannot change the Android Lifecycle, it is always set.
I would advise using Room and LiveData, any changes in the database would automatically update the RecyclerView you mentioned.
You can read more about live data here

Does restarting Fragment also recall FirebaseDatabase

I have 3 fragments and a bottom navigation menu to switch between them.
In every fragment i have a recyclerview to display data gathered from FirebaseDatabase.
My question is: Should i use Replace() fragment? As it would result in restarting the fragment and requesting again Firebase SingleEventValue every time the user navigate between fragments
Or i must use Add Show Hide? Or that would lead in memory leaks?
The methods you use to deal with the fragments are mostly not relevant. The Firebase SDK will cache data previously fetched, so if you make a second request for some data, from any point in your app, you will be seeing cached data, and it will even work offline. There are no "leaks" involved here when using single value events.
Adding a listener to a database location is a different matter. Ideally, listeners should be attached when a fragment becomes visible, then detached when not visible.

Android Service > Activity > Fragment with ViewPager

First, I'd to state that I've been searching for a solution for this problem for three days now, that may means either I'm not asking the right question or not using a good approach. If any, please guide me in the right direction.
This is the scenario: I've an Activity and a bound Service. The Service holds some data and processes it as necessary while posting a persistent (ongoing) notification with some information. The Activity has three Fragments inside a ViewPager that displays the data processed by the Service.
The Fragments are a List Fragment, that shows the active data entries available, a Details Fragment that displays the details for each data and a Parameters Fragment where the user can modify how the data is processed.
[Service] <-> ([Activity] -> [ViewPager([List], [Details], [Parameters])])
Everything works just fine. My Activity binds to the Service, the ViewPager is created after and then the Fragments fetch information trough an Interface.
Here comes the fun part... Screen Rotation!
As the Service binds asynchronously, when the user rotates the screen the Fragments no longer have the data because the Activity is bounding the service while they're already present and not recreated thanks to the ViewPager.
I've been trying to figure this out but it seems that I don't have the knowledge to solve it. I've tried making static references to the fragments, setting them up before the service is rebound but I can't get a stable solution.
I'd be using android:configChanges in my manifest but there are different layouts for each orientation.
Again, if I'm using a bad approach, please, guide me!
Difficult to suggest when I don't know your code but thinking out loud....
Can you have a "worker fragment" that is never displayed (i.e headless) and has setRetainInstance(true) set so it does not lose any state you have set.
Your worker fragment would bind to the service instead of the activity and maintain a reference to it.
If you need to communicate with your Activity, you can do this with callbacks.
Your other fragments could communicate with the worker instead of the Activity.
This process would basically make the activity little more than a shell into which the rest of your components are hosted. Rotation would lose nothing because all data is held in the retained fragment.
During the screen rotation process the activity is completely destroyed and use of android:congfigChange is discouraged. but what you can do is you can override saveInstanceState(bundle) method in which you can save the data present in your activity at the time it is destroyed by the system in response to the screen rotation. and later receive it as the system passes the bundle to the activities onCreate(bundle) method or get it from the restoreInstanceState(Bundle) method.

Android update FragmentManager after it loads new data

I cannot for the life of me figure out how to update a Fragment/entire FragmentManager. I'm using the FragmentManager that comes with the SDK (sliding tabs) and inside one is a form for a login. When the login is finished (which I have figured out, it uses an AsyncTask) I'd like to reupdate the entire FragmentManager section. FragmentTransactions have failed me (or at least I couldn't get them to work) so I'm wondering what's the best way to just refresh the UI.
Also, I have the custom menu with a logout button. When the user logs out, it should also refresh the UI (the tabs change based on whether or not the user is logged in).
TL;DR How do I refresh/reload an entire fragment system from inside and outside of the Fragments?
Also another thing that would be helpful, how do I make a Fragment update with new information (passing an array or a JSON array) after a different AsyncTask completes?
You would have to paste some of your code to see what is wrong with the FragmentManager. Transactions should be completed after you call <FragmentManager>.commit().
In regards to your second question:
To get your Fragment to update with new information, you should be able to just add a method like normal to your Fragment and call it. If you are calling the method from the AsyncTask then just be careful with Context. Take a look at this:
How to call parent activity function from ASyncTask?

Keeping ListFragments in a FragmentPager in sync

Let's say I have a list of homogenous items which is likely to be changed in the lifetime of my Activity by user interaction or OS events. The Activity contains a FragmentPager which shows a number of ListFragments.
These fragments share the previously mentioned data but display it in different ways. E.g. they differ in sorting order or display only a subset of the data. Currently each fragment keeps a separate list containing the respective part of the data in the respective order.
When the data changes, basicly every fragment has to be updated. This means resorting or adding/removing items from some of the fragments. What is the best practice to keep the data in the different fragments consistent?
Currently I have some sort of an observer object, which is notified when something changes and subsequently notifies the connected fragments. But there are a couple of problems:
When the app just started, some of the fragments haven't been created by the FragmentPager, so notifying them is impossible.
When swiping through the fragments some of them get paused. In this state, they can't update their list. Should they disconnect from the observer in this case? This leads to:
When a change happens, while a fragment is disconnected, it basicly misses it.
And so on...
If I understood your ViewPager shows the same data (or it's portion) but in different views. So, I belive ViewPager shouldn't act in any way when data is changed, it's responsibility of Adapter.
About points below you said:
a) creating of fragments inside ViewPager can be managed by you. Just see javadoc of ViewPager::setOffscreenPageLimit(int limit) method.
b) I think you should do nothing with UI when data changed but fragment is in paused state. If you want to update do it in onResume(). Or better to set some field in DB (if you have) to "updates present" state and check it when Activity(Fragment) appears.
c) As in previous option - if fragment disconnected just ignore updates. Or if you really interested in that update use sticky BroadcastReciver (be carefull sticky BR is expensive thing)
You can keep your data in Application class, update only visible fragments when data has changed, and always ask for the new data in Fragment's onResume(), that'll do it
What I would do is have each ListFragment use a Loader to load its data. Then, instead of having the observer notify the Fragment (which might have been killed) to refresh its data, register an observer for each Loader so that it will know when the data source has changed, and will re-query when one has been detected. (If your data source is an SQLite database and you are using a ContentProvider, the CursorLoader will do all of this for you).
This is the implementation I would recommend because
Each Fragments behavior remains self-contained (i.e. each is a re-usable component that is not tied to any specific ViewPager or Activity).
It avoids the complexities of having to deal with potentially destroyed Fragments within your ViewPager.
If you need a quick fix, you could probably get away with forcing the Fragments to remain in memory using ViewPager#setOffScreenPageLimit(int limit) as Ivan suggests... however, this isn't as clean of a solution in my opinion.

Categories

Resources