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).
Related
There is object array received from server
there are two ways to show items :
Adapt Objects To ListView
Use Scroll View
So If I use scroll View and add items programmatically, There are some Questions:
Does Adding Items Programmatically Cause Out Of Memory ?
Does It Need To Remove Items from memory ? or it will remove automatic after onDestroy Called or Items moved out of screen?
Regards
If the data set is large, a ListView won't stop OOMs by itself, you will have to avoid loading the entire data set in memory by using a CusorAdapter backed by some non-memory data store (like a sql database).
A ListView will reduce the amount of memory that the Views use to represent the data to the user, since it will only initialise Views that the user can see (and recycle Views if possible when the user scrolls).
Since only the Views visible are loaded with a ListView, performance should* also be better since the layout process will be quicker.
In most cases, a ListView would be better for this type of thing.
(*) If the adapter's getView or bindView e.t.c. are complex, or each row in the list has its own view type, the scrolling performance could actually be worse.
Listview is the Best case for you. and I will prefer to use volly library of android . It is easy to use and very handy and helpfull.
My problem is similar to ListView getChildAt returning null for visible children, but despite searching I cannot find a solution.
I have a ListView with a Scroll. The ListView has 10 items, 7 of which are visible and 3 are hidden by scroll. I also have an external method (out of adapter) that must get all of the children from this ListView (e.g. using getChildAt()).
I need all 10 of the items, but the last 3 are null objects. I've tried code like the following:
getListView().smoothScrollToPosition();
But this doesn't work.
I think that I don't need to post the rest of my code, as the description says everything?
As you have already seen you can't get all the child row views from a ListView simply because a ListView holds only the views for the visible rows(plus some recycled rows but you can't reach those). The correct way to do what you want is to store whatever data in the adapter's data and retrieve it from there.
But the ListView doesn't keep the current values from RadioGroup in
running time.
I've seen that you have some problems with this so I've adapted some old code to build a basic example, code that you can find here.
I don't think so you need to add scroll view for a listView. Scroll automatically works on ListView. Try your application without adding scroll view and I'm sure it'll work as you needed.
The reason those children are null it's because they really do not exist and they will never exist, if only 7 children are on the screen at one time, the system will only create 7 and re-use by passing the convertView back to the adapter getView() method.
If you want to grab information regarding your whole dataset you should search on the dataset itself, instead of the views on the screen. E.g. if it's an ArrayAdapter, loop the array; if it's a CursorAdapter, loop the cursor; etc.
The non-visible children of a listView don't actually exist. When they become visible, one of the redundant views is recycled or a new view is generated. So you can't actually access all the views. Why do you want to? Whatever changes you want to make should be made to the data that populates the views rather than the views themselves.
There are a few point that you need to take care of:
1. List view provides inbuilt scroll functionality, So don't use Scroll view. It will only mess up things.
2. List view doesn't contain ALL the children. When you scroll it, it creates only visible items on run time.
3. If you want to get all the children altogether, Better keep an ArrayList of the child objects that your list has. You can add or remove children to this ArrayList as per requirement.
I have a ListView that displays a list of items, each of which has an icon and a few bits of text.
I am making use of the "convertView" parameter of the ListAdapter.getView() method, altering an existing view rather than creating a new one when the parameter is non-null.
I had expected the ListView to recycle old views only after they had scrolled out of the visible viewport, but this appears not to be the case. It appears that the ListView is providing the same object in the "convertView" parameter on each invocation of ListAdapter.getView(). The single view is rendered to the screen, and then sent in again on the next call to getView().
This poses a significant problem for me, as I wish to modify previously rendered views. I have a background thread retrieving the icons for items, which takes "considerable" time and would be an unacceptable user interface burden to place within the ListAdapter.getView() view rendering code.
Is there any means to make the ListView not reuse views which are currently displayed on the screen? I'd like to realize the performance/efficiency gains of view reuse and be able to load the icons in a background thread.
I think you're having a similar problem I had for a while: Old items visible a while, in listview or gridview, when recycling
You have to "reset" the recycled items of the list at the beginning of getView(). Set them back to progress bar, or invisible, whatever the initial state is. Until they fetch the correct data.
I've found the issue is that Android is creating an additional, never-rendered temporary view for use in layout/measurement under certain conditions. My assumption that this view was rendered to the screen was not correct.
my viewpager currently only re-renders views that are two views away from what is visually seen.
example (shown respectively)
ViewA, ViewB, CurrentView, ViewD, ViewE
not rendered, rendered, rendered, rendered, not rendered`
how would I force it to reload a particular view X many views away from the currentView, there are some use case scenarios where I want it to, and other cases when I dont want it to. But currently I only know how to reload the entire adapter - where it perhaps pulls from an arraylist
I'm really not sure how to control the Viewpager - very few examples out there. All I know how to do is reset the entire list on "notifyDataSetChanged"
insight appreciated
use this method mViewPager.setOffscreenPageLimit(2) and you can set the limit of offscreen pages
I think your going too need to decouple your view and data logic (array list in this case?). If you don't want the view to change, don't change the data layer. When you call notifyDataSetChanged everything will mimic your data layer. If you want a view to change, change the data layer and call notifyDataSetChanged.
To put it simpler, the view just draws what the data tells it to, and expect that the view could update at any time. It is very similar to how listview works.
Is there a way to call BaseAdapter.notifyDataSetChanged() on a single element in the adapter.
What I am trying to do is update the data and reflect those changes in the containing ListView. The problem is that sometimes the change is so small that it seems ridiculous that I have to refresh the whole view rather than the single item in the view that has been updated.
I am not aware of such method. If it's really important, you can always find individual item view to update. But I don't think that it worth it as Android is pretty efficient in updating list views. So it will not do much extra work (definitelly not going beyond items currently visible on the screen).