Save custom ArrayList on screen orientation change - java

I have a ListActivity where the ListView is driven by a custom array adapter which has custom objects in it. The custom object is a Site.
On orientation change, my current implementation is trying to hit the database again to populate the ListView and I want to save the current ArrayAdapter then re-attach it to the ListView after the orientation change.
Whilst I wasn't keen on it, I resigned myself to the fact that I would need Site to implement Parcelable so I could then save the entire ArrayAdpter to the bundle as an array of Paracables.
I have looked at this post which does pretty much what I need to do.
However, my Site object has variables within it which are also custom objects and those objects themselves also have other objects such as DateFormat in them. I can't figure out from the post that I linked to above how to implement this so that the objects within the objects that make up part of the Site object can be included in the Parcel, since this example only deals with strings and the parcel doesn't seem to have a writeObject() method!
Are there any alternatives? (I'd love to avoid using Parcelable at all, but if I have to that's ok)
thanks
Aaron

You are using ListActivity, that means your UI is similar in both orientations ?
If yes, you can avoid the condition of recreation of activity on orientation change by adding android:configChanges="orientation|screenSize" in your manifest for this activity.
If not, then you should use a FragmentActivity and make a listview in that, and then you can use onRetainCustomNonConfigurationInstance() to return your adapter object and after configuration changes get it using getLastCustomNonConfigurationInstance()

Related

Correct approach on using RecyclerView?

My task is to develop a list of different type of questions, a survey. It could include types like Integer-Answer-Question, Long-Text-Answer-Question, and so on.
Why is it needed to be a list? Because for the people using the app is way better to scrolldown answering each question rather than swiping to right, or doing another movement.
So I was face to face with the dilemma of using a ListView or a RecyclerView. My research gave the final outcome of using a recyclerView and having a viewHolder for the different types of questions that I have.
The struggle came when I realized that there is a type of question that has dependency related to it; how so? if you select one option then you have to "show" some questions, and if you deselected this option then you have to "hide" it again.
The thing is that I need to know the reference of each question to their viewHolder in order to "show" o "hide" each of them, but if the recycler is recycling viewHolders then it could create a mess on my logic.
My punctual questions are: Am I using the correct component with the RecyclerView?, is there any way to access a viewHolder with a unique reference, like and id or something?.
if you need me to show some code, I'd do it happily.
Valuable information:
if you are interest in how notifyDataSetChanged() works you can access to this link for further and detail information.
Minas mina's approach was the correct one!
If I understand correctly, you need to hide some types of questions when the user selects an option.
Your understanding of what the view holders are supposed to do is not quite right. The view holders cache a bunch of views that you later use in onBindViewHolder() to fill-in data from your model objects.
The actual model objects should be in your adapter. In your case, something like
List<Question> questions
In onBindViewHolder(), you fill-in the fields of the View holder with the data from a Question object.
As for your question, what you can do is to set a flag in your recyclerView adapter, e.g. hideQuestionsOfTypeA to true and then call notifyDatasetChanged() on the adapter.
When binding objects, check if that flag is true and if yes, set the visibility to GONE to the views that need to be hidden.

Handling empty lists - better to use ListFragment or Fragment+ListView?

I have some doubts. I'm trying to make an application with lists. I made one but with a ListAdapter extends BaseAdapter and ListView.
Then I realized that there is also ListFragment. And with the fragments you can easily display messages "empty list". What I want to do is a list of items and each item associated with this single_item.xml for example. I have seen several examples, but there are differences between them and me is not good either choose from.
Which is the updated method to do this and has the best performance? Are ListFragment better than ListAdapter extends BaseAdapter?
Thanks in advance.
ListFragment essentially provides shortcuts for interacting with a Fragment whose layout contains a single ListView (and nothing else, by default). The ListFragment does not provide any performance advantage, as far as I know. You can inspect the source code here if you would like to know more about how the class functions.
My preference is to avoid ListFragments - I find them inflexible if the layout of a screen ever needs to change, plus they use slightly differently-named APIs that can be somewhat fiddly to remember (onListItemClick, vs the onItemClick callback of a standard AdapterView, for example).
Here is a good article that describes how to handle empty ListViews. You are looking for the setEmptyView(View) method of ListView. This allows you to specify the view to be displayed when the ListView is empty.

how to know in the main layout that a ListView has been changed?

Suppose that I have a main layout that has a ListView. This ListView has a custom cursor adapter. When my list change, is there anyway to know, in the main activity, if my list has been changed?. Inside my custom cursor I call to this.notifyDataSetChanged();. Is there any method that can I use to know when notifyDataSetChanged() has been called?.
You need to create a DataSetObserver and register it with your adapter by calling registerDataSetObserver().
p.s. I strongly suggest that you familiarize yourself with the Android API Reference. This is a great tool to help you find the classes and methods which are available in the Android API.

Change fragment content when page changed, ViewPager

I have a ViewPager, that i'm populating with fragments which has a listview inside. The point is that i have to show a really big amount of data, and i need to make pages, so i only request littel amounts of data.
My problem is that i need to call an asynctask to retrieve the data when the page is changed, and fill the listview of this page, how can i do this? How can i change that listview in the onPostExecute of the task?
PS: i have used an eclipse template for tabs + swipe activity, so im not posting my code.
I'm not sure I got your problem right, but the first thing that comes to my mind, is that I would use an AsyncTaskLoader instead of a simple AsyncTask. From my (limited) experience, loaders solve a lot of problems when it comes to Fragment/Activity lifecycle/configuration changes.
Loaders guide (Android Developers)
No matter what method you are using to get the data, changing the content of the list view in page B after loading the data in page A shouldn't be much of a problem: you have plenty of options, from simply saving the data for page B in the Activity (then changing the page with setCurrentItem and intercepting the page change event with setOnPageChangeListener),
to a more elegant approach employing a SQLite database (which btw would allow you to do some caching on the results, if possible).
Oh, and let's not forget that, if you are using an implementation of the abstract class FragmentPagerAdapter you can probably pass the data directly from one page to the other, as this PagerAdapter implementation
represents each page as a Fragment that is persistently kept in the fragment manager as long as the user can return to the page.
(just use getItem(int) to get a reference to the page you need. I never tried this myself, though).
Hope this helps
EDIT I just found out that getting a reference to the current Fragment shown in the ViewPager is tricky if you are not using a FragmentPagerAdapter: if this was the root of your problem, information about how it can be done can be found here:
Update data in ListFragment as part of ViewPager
Retrieve a Fragment from a ViewPager
Communication between ViewPager and current Fragment

Android - CursorAdapter-ish Subclass, for ListView

I currently use a bunch of subclassed CursorAdapters with custom layouts throughout my app, populating them with a Cursor returned by an SQLite query, then allowing them to populate my ListView, after setting them with
setListAdapter(new SearchAdapter(this, searchCursor));
Is there anyway I can get the same behavior but instead of passing in a Cursor pass in an
ArrayList<String[]>
Would there be a different class to subclass? (Obviously) Or, should I convert the ArrayList to a Cursor somehow? Or, is there a different method I am missing?
Thanks!
you can do it with an array Adapter (also you can subclass Base adapter) and implement your own way of displaying objects in a list. there are plenty of tutorials on google on how to do that.
Just search ArrayAdapter, Base adapter. :D
Hope this helps,
Take care.

Categories