Context:
I want an action button that will allow the user to select some stuff form a list.
I'm considering using an ActionProvider for this.
My data is retrieved from a REST service and cached locally in a DB.
Problem:
ActionProvider doesn't seem to support loaders. (or am I mistaken?)
If I just load the data using a query, it will not get updated once/if the new REST result comes in. In fact, the first time around - it will be empty.
Questions:
0) Is there a way to do what I want in an ActionProvider?
1) Should I be using this approach over a plain old Activity?
PS. Could someone add 'actionprovider' as a tag? :-)
10X
How about creating a fragment with no UI, but with setHasOptionsMenu(true) and onCreateOptionsMenu() implementation instead.
The fragment could load the data via loaders, and when ready invalidate the options menu, populating it with the required list.
You can attach such fragment to your activity and it will take care of its life cycle, while having this feature in a separate class.
Related
For my current project, I will be using this SlidingUpPanel library.
The sliding up panel will host a fragment that will contain application/global level information. This panel will be in every activity in my application. This will be very similar to the way Google Play music works.
My question is, what is the best way to persist the sliding up panel fragment throughout my application? I see myself going about this in two ways...
Storing the fragment inside the Application class and loading it at the start of every activity (somehow, not even sure if this is a possibility).
Storing the data that it will display in the Application class & loading a new instance of the fragment, passing in the persisted data.
Which one of these two ways would be the best? Is 1. even possible? Are there any coding landmines with these approaches?
Storing a fragment to persist throughout the application lifecycle would be pretty unorthodox, mainly because the fragment class should be able to follow it's normal lifecycle events (in this case, mainly onPause and onResume) instead of being stuck somewhere in the application class.
It is definitely common practice to store the data and load it each time you display the fragment. If you want to enable some sort of cacheing or singleton pattern to access the data, it should most likely be with another object that the fragment can access but is not a member within the fragment.
There is a good video from google about leaking views and it touches briefly on the pitfalls of doing some similar to what you're proposing in bullet #1.
I think the structure of your app looks like it should be a single activity where that bar is in it, then the main content is a Fragment that you replace and use addToBackStack on in order to maintain the use of the back button. Otherwise, you are going to have a lot of repeated code with solution 2 (which means a lot of repeated work in the case of bugs etc., not very maintainable), or leak views using solution 1.
More info on providing a proper back implementation
I have a List of items that I want in a ListView, and I can make it work with setting a custom adapter every time the List grows, but the program flow is kind of weird and I have problems with persistence. (If I switch tabs, the UI gets rebuilt with an empty ListView.)
Now, in my day job I'm a C# developer, so when I look at this problem I see a WPF ListView bound to an ObservableCollection. Does Android/Java have something like that, a "fire and forget" connection between a UI element and a data structure?
You don't need to replace the adapter every time you change the data. The adapter "adapts" between data and view. There is no need to change the adapter as long as the way it adapts does not change.
Activity / Fragment lifecycle is not necessarily the lifecycle of your data collection. You can for example make a singleton data collection somewhere and use an adapter to display that collection all the time. Call .notifyDataSetChanged() on the adapter if you changed the data.
A persistent data collection in Android is probably best backed by a database. Take a look at LoaderManager & ContentProvider to provide and load data then displayed via CursorAdapter.
There is no automatic way of keeping a bunch of data available outside of your Activity / Fragment / .. lifecycle and it can get quite complicated but that's basically what you have to do if you want to keep data for longer than a given lifecycle. Singletons, Activity#onSaveInstanceState(), Activity#getLastNonConfigurationInstance(), Fragment#setRetainInstance(), ... are useful utilities to keep data in memory, databases are good for persistent data.
You have to do a little bit work yourself but it's possible. Use a ContentProvider as your DataSource. How the data is stored is up to you. I would prefer a SQLite-DB. A content provider has the possibility to add ContentObservers. (See this related question.)
You can write a CourserAdapter to fetch the Data from your content provider. And your ContentObserver should call notifyDataSetChanged() on your adapter. This closes the circle and your UI refreshes itself.
In Addition to zapls answer:
You can also write an adapter which contains a BroadcastReceiver. When your DataSource changes you can send a LocalBroadcast. The broadcast handler just calls notifyDataSetChanged() of your adapter. I think this would work around most of the lifecycle problems because only active elements will get the broadcast.
The google documentation has an example for such a solution.
Will try to explain what I need to achieve:
My activity is used to display some user settings. Just for users, to make it look nicer, I need to use ViewPager with 3 pages: general settings, another settings, different settings. When activity starts I get all settings using http async task. So i need to fill all my 3 pages with the data from http responce. So user can scroll left/right to view different pages and change settings. On action bar I have button save: when press it, it should take all the data from each page and send http post request in order to save data.
Which type of adapter do I need to use for my ViewPager in order to achieve it? Currently I use "FragmentStatePagerAdapter", but it gives me access to the current/displayed fragment. But I need to be able to get/set data from every fragment, not only current one.
Can someone give me any hint how I can do that. Shoul I use FragmentStatePagerAdapter or just PagerAdapter will be enough? Or maybe there is another way for it)
Any tips will be very helpful. Thanks
Loading the data and displaying it are different tasks. You can of course download all the data that you will need and store it in the adapter itself. Once the adapter gets a call to getItem() you initialize a new fragment with the data for the given page and return it.
Also, use a FragmentPagerAdapter because it is a lot more lightweight. In the api docs you can actually see how a new Fragment is created an returned.
I'm doing my first app, a RSS Feed application, for learning the multiple technologies associated, like xml, parsing, connecting to the internet, getting the information, processing it, etc.
I've decided to use the newest Android elements, such as the Action Bar and Fragments. So I've done an action bar with a few options, like Refresh (which refreshes the RSS list), Preferences, About and Exit. The main issue is with the Refresh.
I'm pressing Refresh and the option creates an object which will get the XML, which should return the information for the newsList Fragment. But I can't pass the information to the fragment, but I also can't Toast the xml information to the screen, so I cannot test if I'm getting everything correctly.
My programming background is not in Java, I'm used to Web Developing (PHP) and scripting (Shell) so I guess I'm missing some basic stuff, which I apologize in advance.
Can anybody at least give me some hints, in order for me to know what to search and get back in the right path?
Thanks a lot!
So you have the class that handles the downloading/parsing of the RSS feed, but you don't know how to pass the processed feed-info back to the ListFragment right?
There're multiple ways to solve this. You could use the callback pattern for your rss-retrieving class for example. So the Activity starts off this rss-retrieving object asynchronously, and registers itself as a listener of this object. When the rss-stuff is done, the object notifies your Activity about this through the listener-interface.
In response, the Activity can get a reference for the ListFragment (using the FragmentManager) and call a method on it that refreshes the list, passing in the parsed RSS-info as a parameter.
I am still searching for the best solution howto use a layout with a menu and a toolbar and inflate or start activities in android. My question may sound confusing, but im trying to explain it in an example.
Lets say im programming an android app (surprise.. i really do)
My app can do following:
User can log in [3] or register [2]. If he logs in, a new activity starts and his dashboard will be shown. If he registers: an activity for the registrationprocess starts.
Registrationprocess: user puts in his desired username and password and presses a button to accept. His data will be formvalidated and if valid, a new activity starts where he can choose his settings. Backbutton works and data can be passed to the new activity. After the last registrationwindow data will be saved and dashboard started. Starting new Activities is fun!
Now THATS where it gets complicated. Dasboard has an 'actionbar'(top) and a 'toolbar' (bottom, like tabs). So everything should be viewed in the middle part of the viewport(from now called main view). No more activity switching :(, tho.
Currently each tabclick removes all views from the main view and adds its new view. Look great, can be animated and works like a charm. Except: its currently not dynamic.
So... i don't know how to solve it the best way. For example: i fetch data from a webservice, create a listview out of it and it's extending listactivity. This activity i can't start but this data need to be put into the main view. How can i do it the best way?
And is it efficient?
I'm practicing and it's actually my first small discussion i want to start. So... FIGHT! ;)
UPDATE:
I've seen an interesting way to start activities and get results.
Launching activity through intents
. Is it possible to insert new/ update views after activity started? I would then generate my results in a separate activity. Update the view. Return back to 'dashboard' and load the view that was just updated. Possible? Or inefficient? And how can i update a view out of another activity? There is so much i need to learn :/
UPDATE2:
A good example of an app that has done it: Google+
Too bad i don't have their sourcecode ;)
UPDATE3:
What is best?
load a new activity, disable animation and set selected toolbox tab +
disable backbutton functionality
startActionForResults, fetch results and update current view (still don't really know how that would be possible)
viewFlipper onflip changing+updating data in flipped view.
I still don't know any efficient solution. Or am i missing something essential? I've just finished my ListActivity to fetch data from my webservice. But it still runs in a separate activity. How can i implement it into my "main view" now? Ofcourse... i could set a list my custom adapter. But currently im updating and fetching data from the server when i create the listactivity.
Im afraid this could be the only answer i'll get: Embed external Intent in main Activity
UPDATE4: I'm trying something.
Based on nininho's answer (thank you!) im trying the following approach:
Start Dashboardactivity and create a ViewFlipper.
Each Toolbarclick represents a certain ViewFlipper page.
Each Page has a Listadapter implemented and shows different results (different webservice queries). (ListView, GridView, with profileimage, without profileimage)
On Toolbarclick start AsyncTask or Service and notify List in current Page that data has changed. (ofcourse IF data has changed). Switch to page that was clicked.
Implement updatefeature. On scroll to bottom of list = fetch more data and add it. Update other lists automatically after 5min. or update list on update-button click.
PROs so far: Backbutton standalone for whole activity. Page-flip-animation possible. Async updating of lists and still possible to switch to another list.
CONs: ... someone has any? What about efficiency of such an approach? Does the ViewFlipper carry all the information so the performance would go down or does the viewflipper recycle its Views (like ListView)?
UPDATE5:
If i have some time i will make everything here more read- and discussable. Don't be mad at me for reading my rubbish ;)
From what I understand you want your app to start, fetch some data from the internet and after show this data on the main screen.
I don't see the need of a second activity to fetch the data because from your explanation you want to use it only to fetch the data, so the best approach would be:
Create one Activity (your dashboard)
Start an AsyncTask or Service on the background to fetch the data.
When the fetch ends, notify the activity that it ended.
Change your dashboard to show the list (you can use a ViewSwitcher if you want some animation or just create a layout with the list invisible and then change to visible).
ps: you can use a ListView outside of a ListActivity, just create a ListAdapter to create the ListView items and add this as the adapter for the ListView.