Update Custom Fragment from ContentProvider - android

I am implementing two fragments to display different views on the same table retrieved from a ContentProvider:
1/ A class which extends ListFragment to provide the data in a list
2/ A custom fragment class which itself contains a Google Maps v2 fragment
The list fragment is a standard implementation using a loader and SimpleContentAdapter, so when the name of a list item is edited in a seperate activity, the change is reflected back in the list.
I want to do something similar with my custom fragment so that map markers are created and updated as the data changes.
What is the best practice for doing this?
It appears that using a SimpleCursorAdapter would not work since it returns View objects whereas I need to create/update Marker objects and these are not derived from View. I'm thinking along the lines of creating my own CursorAdapter class, implementing ContentObserver on my map fragment container and registering this with the CursorAdapter. Is this best practice? Does anyone know of any sample code demonstrating best practice?
Sorry if this is a stupid question - I'm new to Android programming so not completely clear on the notification architecture - but I have tried reading around the subject to no avail.

Okay, I've worked out the answer to this. There is no need for a CursorAdapter or a ContentObserver. The steps are as follows:
1/ Create Fragment-derived class (in my case derived from MapFragment)
2/ Implement LoaderCallbacks on this class
3/ Call getLoaderManager.initLoader() in onCreate() override of this class
4/ Create a new CursorLoader() in your LoaderCallbacks.onCreateLoader() override
5/ In LoaderCallbacks.onLoadFinished(), call code to iterate round the cursor and populate your view. But DON'T CLOSE THE CURSOR OTHERWISE YOU WON'T RECEIVE FURTHER UPDATES!!!
My problem arose from adapting some sample code in which the cursor.Close() was called once the list had been populated. I guess good practice is to save the cursor in a private data member and close it when LoaderCallbacks.onLoaderReset() is called.

Related

Correct architecture when accessing data from many different fragments

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.

Updating a ListView With CursorAdapter When Querying Database

I have a ListView and an CustomListAdapter that extends CursorAdapter. I'm using a LoaderManager to load the data into my CustomListAdapter when I first load the Fragment containing the ListView. That all works fine. I'm using ContentProviders so any updates or changes to the underlying data in the database are reflected in the Listview.
Now I want to allow the user to search for specific items in the list. So in other words i want to update the list view based on the search query obtains from the SearchDialog. I've got the SearchDialog working and I'm up to the point where I receive the intent in ParentActivity of the ListViewFragment, with the search query. However I'm not really sure what I should be doing now.
I was thinking of detaching and then re-attaching the Fragment to the ParentActivity passing the search query string to the ListViewFragment so that the onCreateLoader() method of the fragment could use the query to do another search. This seemed like an easy way to achieve what I wanted to do.
Is this the correct way to update a ListView based on a search? Or is this overkill for what I'm trying to do? Does anyone have any other suggestions?
Kind Regards
For anyone that wants to know, my requirement changed and instead of using the same Activity to view the results, I sent the results to a new SearchResultActivity that was re-using the ListViewFragment.
I created an instance variable on the ListViewFragement that would store the query string. When creating a new instance of the Fragment, it expects a value for this query string. When I load the Fragment from my first Activity, the string is null and the onCreateLoader() by default loads all the results. When I load the Fragment from SearchResultActivity I pass in the query result from the SearchDialog and the onCreateLoader() will use the query to return a Cursor based on a specific selection.
I didn't need to attach and re-attach the fragment in anyway. However if I was to use the same Activity and ListViewFragment to display the search results, instead of detaching and re-attaching the fragment to the activity, I would probably use the restartLoader method of LoaderManager:
LoaderManager Doc

Placing AsyncTask in Activity or Fragment?

I am trying to design an Android app which:
grabs JSON data from an HTTP link
iterates through the data and forms an ArrayList of my Object.
Now the HomeActivity extends an ActionBarActivity, which implements TabListener.
It has 2 tabs with a Fragment in each. Fragment 1 is going to hold a listView from the JSON data. Fragment 2 is going to show a Google Map with markers based on the same JSON data.
Now, I'm just wondering what is the best approach to use this AsyncTask.
Should I place it in the Activity and then use interfaces to pass that ArrayList to both the Fragments?
Or ... how should I do this? Thanks! Some tips on caching would also help.
Yes, if your fragments are both using the data, it seems reasonable to put your AsyncTask in the activity. If the AsyncTask is a non-static inner class of the Activity, then in your postExecute you can fetch pointers to your fragments from your activity, and then call methods on the fragments to give them the new data (or tell them that you have stored it somewhere -- however you've implemented it).

Share CursorAdapter instance between Activities

I have an activity that loads result from the database using ContentProvider and LoaderManager.LoaderCallbacks interface and displays in a list. It works fine no major problems so far.
Now I want to display detailed view in another activity after clicking on the list item, I was thinking that if I already fetched the data I could share the CursorAdapter instance and this way have it reused and make possible to change content from within the DetailedView by flick gesture.
Q: Is it possible without leaking memory in the application?
Q: If not then how to accomplish this?

Best way to access a parent Activity's data

This is a stylistic question more than an actual "how can this be done," but the basic situation is this: I have an Activity MyActivity which contains a MapFragment, as well as a List of Renderers which are my own class that takes care of displaying some data. The Renderers also have ViewPagers which get their content views from yet another class, let's call it ViewPagerTab. Sometimes, something happens in some of these ViewPagerTabs that necessitates the update of the map in the top level Activity. There are, as I see it, a few approaches:
1) Both my Renderers and my ViewPagerTabs contain a reference to the context. If I cast the context as MyActivity I can access its map parameter.
2) By using the reference to the context, I can call getSupportFragmentManager().findFragmentById(R.id.map)).getMap() on it and get the map that way.
3) I can pass the map down from the Activity to the Renderers to the ViewPagerTabs as they are created so the map is accessible in each as a class variable.
4) Use a BroadcastReceiver in my Activity and send a message to it when the map needs updating from my ViewPagerTab.
Have I missed anything? What's the best/cleanest way of doing this?
This lesson may give you some ideas:
Communicating with other Fragments
Basically, the idea is to define an interface in a subunit such as a Fragment, then implement it in the parent Activity. Then, actually call the methods in the interface in the Fragment.
Another alternative is to create a class that extends Application. There, you can "share and declare" a number of non-context specific variables (like a glorified container, but where you don't have to create multiple instances of, or do look ups).
Requires some setup in your manifest but then all your activities can call MyApp app = (MyApp) this.getApplication(); (or in fragments, via the onAttach activity's .getApplication() )
The standard way is to define a listener interface, but I've found this to be cumbersome. Otto is a really nice alternative that you should at least look into before making your decision.
I think this is a bit over my head but what about parcel.I think it wouldn't work because of the dynamic nature of your data however it is one way to communicate between activities.

Categories

Resources