how to saveInstanceState of a view defined in getView() method - android

I have MainActivity with a ViewPager that hosts three tabs and their respective classes extend Fragment. One of the tabs has a layout with a ListView, the
layout of the each item in the listView is as follows
TextView, checkBox and imageview
This ListView has customized adapter class that extends BaseAdapter.
What I want to do is, to save the check state of the Checkboxes of the ListView.
in the class that extends Fragment I override the method onSaveInstanceState, the problem is the checkBoxes are defined in the getview() method in the
class that extends BaseAdapter! I want to know how can I save the check state of the checkboxes in the method "onSaveInstanceState"?

I think you might be misunderstanding the purpose of BaseAdapter. BaseAdapter-derived classes are meant to serve as an interface between a dataset and the AdapterView in which you display that dataset's information (and/or interact with it.)
With that in mind, I kind of think the easiest way to accomplish what you're doing is going to be to keep track of whether or not the item is checked using a boolean as part of the dataset. For example, if your dataset is an ArrayList<SomeObjectYouMadeUp>, you'll want to add a boolean member to SomeObjectYouMadeUp; set it during the CheckBox's OnCheckedChangeListener, and use it to determine whether the CheckBox should be visually checked during getView().
That might take some rethinking of your code, but trust me, you're probably going to want to do it. It's possible to do it the way you are describing, but it won't be easy or reliable; you'll want to get individual access to each visible view in your AdapterView using the method described here, but again I have to recommend against this.
The biggest reason is that onSaveInstanceState occurs most commonly during configuration changes - for example, a screen rotation. This means it is almost certainly an incorrect assumption that you'll be displaying the same Views. Say there are 10 Views visible in portrait orientation, and 5 visible in landscape. So the user rotates to landscape - which 5 do we get? Do you know for sure? You'll have to check each new View against some identifying information you probably also had to keep in onSaveInstanceState - and what if one of the new Views wasn't visible before the rotation?
The list of questions goes on. Do yourself a favor: save the check state with the rest of your dataset, and let Android figure it out for you.

Related

Access Adapter items of Recyclerview

I'm using Recyclerview to show a list. I want to delete some items like IOS. In my listview template I have added a button to delete item which is invisible by default. In my activity I have another button attached at bottom (Not part of listview) and on tap of this button I want to make all delete buttons of listview visible.
My Question is how can I get reference to all delete buttons of listview in activity and is it the right way to do this?
Thanks
Assuming you have ViewHolders set up, you already have references to all the buttons in your list. All you have to do is to make them visible for every item in the list with a simple loop.
In case you haven't implemented ViewHolders I suggest you check out the documentation and take a look at some simple tutorials on how to use them.
On a side note. If I understood correctly you're making a bottom tab for your app and since you referenced iOS I gotta say this; Remember that Android and iOS are two unique operating systems with their own ways of handling things. Check out Googles pure Android documentation.
In your question title you say RecyclerView, but in your text you say ListView. The solution is similar either way, but it's best to be perfectly clear what you're doing.
In either case, there are at least two different solutions.
First, you could use a boolean flag to determine if all the the item buttons should be showing or not. You check this flag at the time the item view is inflated or created and toggle the button accordingly. If the boolean flag is ever changed, the easiest thing to do is tell the RecyclerView/ListView that the underlying data has changed and to redraw all the views. Call notifyDatasetChanged on the adapter.
The other thing you can do at the time the item buttons should change is iterate all the visible item views, find the button, and change its visibility. With RecyclerView, you can do this, and with ListView you can do this.

Showing animation of Views created from a custom adapter

I'm trying to show an animation with all Views that I've created from an adapter. When I scroll down, it shows the animation correctly, but when I scroll up, I see these Views recreate themselves and show the animation again. Then, when I scroll down, it happens again.
My assumption is that the mechanism of creating a View from an adapter is to load the View into memory; just the group of Views which are on screen right now (but above and below views are not loaded into memory). These will be loaded again when I scroll to these views, right?
Is there any way to fix this problem?
PS: Sorry for my English, I hope you understand my problem.
My assumption is that the mechanism of creating a View from an adapter
is to load the View into memory; just the group of Views which are on
screen right now (but above and below views are not loaded into
memory)
That's somewhat correct: a ListView will not try to visualize any data that isn't (at least partially) visible. It also 'recycles' views, meaning that any view that isn't currently used to present data to the user and is of the same 'type' as the next data item, may get reused.
Hence you shouldn't rely on persisting data with or make any assumptions about the existence of particular views. In stead, use something that's separate from the views; e.g. the dataset you're visualizing.
Quite often, you'll supply a list of POJOs to a BaseAdapter or ArrayAdapter. You could simply add a boolean to the POJO indicating whether it should animate or not, and change that whenever the animation for that particular item finishes. Alternatively, you could keep track of these values in a separate collection (which is probably the more straightforward approach if you're dealing with a Cursor as data source rather than POJOs).

Android ListView not retaining values through orientation change

I am a bit perplexed on what Android holds onto in a view orientation change and what it doesn't.
Some things it seems it holds onto nicely, other things it seems it doesn't.. So I am not sure if it is my code, or something else. (I assume I am doing something stupid)
What I have is a view with a listview in it, the listview has a simple adapater and an array of map items to put into the listview.
When the orientation changes, I know that the activity is destroyed and recreated, so I assume that my simple adapater and its tie to the listview are gone.. so the listview won't rotate populated and I'll need to use the onRetainNonConfigurationInstance or onSaveInstanceState methods to pass through either the adapter or the list of values?
This seems excessive, I can't believe the sharp guys at Google don't have an easier way to handle this.. The listview has an ID, and after orientation I can add items to it and it works fine, but it just doesn't hold onto the values it had before.
Is my only way around this to pass the list content through explicitely? Is it the fact I am creating a new SimpleAdapter and linking it to the list in the onCreate that is causing the issue? Or is it the fact the array of Items I have linked to the adapter is whiped out when the activity is?? This seems like something that shouldn't require this much work to accomplish.. am I missing something?
No, you could also have a persistent model through Activity lifecycle like this :
define a singleton app, with a method to get your singleton model.
At on create get your datas from your model.
As your model will no be recreated but will persist, this can be used as a workaround for preserving objets through rotation change.
Regards,
Stéphane

Refresh view display when underlying data changes

I have seen this question answered a few times in which it is suggested to use the method notifyDataSetChanged() from BaseAdapter.
Is there a way to refresh when your application does not use any adapters? I have a simple application where I use a few activities with preferences, and relative layouts with text views and buttons. At the moment I do not use any of the adapters like SimpleAdapter or ArrayAdapter or CursorAdapter. It seems like in my case I have to create one of them just to get to use notifyDataSetChanged()? There is no easier way for me?
Looks like (I may be mistaken, but it really looks like) you don't catch the purpose of those classes - SimpleAdapter, ArrayAdapter or CursorAdapter. They are expected to work with ListView inside of an Activity (or even better - inside of a ListActivity). If you don't use ListView then those adapers are most likely useless for you.
I assume you have your data persisted in some way (SharedPreferences or file). So if you start any of your Activities, then it just reads the data to populate the views. In this case nothing extra is needed. In case if you need to reload data for a currently visible Activity, then just reread the data from persistent storage and repopulate the views.
If your data is changing and you need to refresh your view, how is the data actually changing? Is it in a separate thread or, do you just want something to happen periodically (polling an RSS feed, or something)?
I had a similar problem. I had a radio group, and each radio button had a label. When the screen rotated, I used a different layout with a radio group & radio buttons with the same IDs. I was calling setContentView() in onCreate(): and after rotation, the “old” labels would show up on the new layout (bizarre). When I moved setContentView() to onResume, everything seems to update ok. Thanks to Arhimed for his answer above.

android access listview row from another row

Suppose I have a listview with 3 rows. If the user clicks a button in row 1, it expands a menu (it's just a linear layout that's shown/hidden). If they then click on an item in row 2, I'd like to be able to collapse the menu in row 1. Is this possible? If so, how?
Save a reference to the View you would like to manipulate later. Probably wrap in a final variable, then you will be easy to change.
You can always use getContext() on the View to get a reference to the containing Activity, which you can cast to a ListActivity (assuming you're using that) and call the usual methods to get the data at that position in the ListAdapter:
((ListActivity) v.getContext()).getListAdapter().getItem(1)
Then you can manipulate your data however you want to and call notifyDataSetChanged() on your ListAdapter.
But it'd probably be a lot easier for you and your users to just use ExpandableListView, which gives you expandable lists with predictable interactions your users already know. You can check the history activity in the Browser source code in AOSP for a real life example. And if it doesn't exactly meet your needs, you can always yank the code for ExpandableListView itself from the Android source.

Categories

Resources