Android custom cursor adapter and BindView - android

Ok, I hope I don't get slammed for asking such an ambiguous question but I am stumped and don't even know how to ask this. I am going to try as best as possible to communicate my problem and will clarify if needed.
I have two cursors merged using MergeCursor. I also have a custom cursor adapter. In my custom cursor adapter I have overridden BindView. I am noticing strange behavior where items are not showing up in my listview. Essentially I have two textviews for each row in the listview. In the last row one of the fields is empty.
I step through the BindView and I notice it gets executed 3 times. My listview only has 7 items in it (so that's 7x3). All of them show on the screen except one of the fields in item 7. I notice that on two passes though BindView a field value is missing.
What I want to know is, why is BindView executing 3 times. So when I say 3 I mean 3x7. 7 items in the list, so it cycles through BindView 21 times. I hope I'm making sense.
Please don't slam me if this is not clear. I am happy to modify or provide additional info.

What I want to know is, why is BindView executing 3 times. So when I say 3 I mean 3x7. 7 items in the list, so it cycles through BindView 21 times. I hope I'm making sense.
When ListView goes trough the measure phase, it will call newView and bindView on your adapter so it can set the dimensions of the rows (its children) and determine it's own dimensions. In the process, it doesn't retain the views, so they need to be recreated when the views are drawn on the screen. You can look at the ListView source so see exactly what it's doing.

Related

Notifydatasetchanged() between adapters

I have 2 recycleviews and both of them have a number of icons. I also have a list that contains a number, which is the number that represents which icon has a background that shows it has been clicked.
Now, the problem is that I only want one icon marked, with this I mean 1 item in total of those 2 recyclewviews. The way I've tried to do this is having a json that saves a number that determines which recycleview should have a marked item, if it doesn't have the number of the recycleview, then the background is the normal one, that way only one recycleview has a marked item.
The problem is that for that to work I need to call the method Notifydataserchanged() on the other adapter so the marked background dissappears, and the easiest way of doing that is putting the other adapter on the constructor. The problem with this is that only works for one, because since the other is declared before you can't construct it with the adapter that comes after it.
I've seen way of doing it with listeners/interfaces made in the activity and then
moved to the adapter itself so you can just call those methods, but it hasn't worked for me.
Any ideas? Thanks

Listview row requestLayout() and View recycling

I'm having some difficult time figuring out when the ListView decides to recycle all it's views. I have 2 different ListViews where i change some layout stuff and play an animation after that. In my first ListView this works fine, only the row i'm trying to change is actually being affected, yet in my other ListView all rows are affected and the Views are being reused.
I can't really post any code, as there are quite a few classes involved in this. I tried to break it down and noticed it reuses the rows after calling requestLayout() at one of the descendant views of the row. But in my other ListView i do the same and it's not called at all.
Nowhere in my code notifiyDatasetChanged() is called either, nor am i changing any other views.
I just trying to find out when ListView actually needs to reuse the views.
ps. I'm using 2.3.3. And i'm aware of setHasTransientState() in 4.1. But i can't use that unfortunately
I found my specific problem.
After long debugging through the source of the ListView I found the difference in behavior between my two ListView implementations. I found out that one of them was calling onSizeChanged(), first to a new height immediately followed by another onSizeChanged() with the old height. In this method it sets a flag mDataChanged which in turn will cause the views to be recycled.
In my other ListView i have fixed row heights so it never has this problem. I'm going to do the same for this situation as i don't really need different row heights.

How to get all children (visible and invisible) from a ListView?

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.

Android: avoid unwanted calls from getView() in an adapter

I searched for hours but didn't find a suitable solution for me.
What I want to do: in my ListFragment I use the onListItemClick(...) method to handle the click events. Here, I change the background of the row item. But unfortunately every time the onListItemClick(...) is called, also the getView() from the adapter is called and updates all 8 visible row items. That takes to much time: 0.5 seconds. Because the row layout is pretty complex (2 Images, 8 TextViews).
So I want to update only the row which is clicked. I want to use this solution but that has no effect, when the other 7 row items are updated anyways.
I already followed these advices to speed the list up, but it's still to slow.
Any help, ideas and thoughts are appreciated. :)
Thank you!
[EDIT]
Thanks to CommensWare for giving me some new ideas. What I did now was to check what traceview says. And the result is, that the delay is devided in two parts. The first 300ms of the delay takes the "FastXMLSerialzier.escapeAndAppendString()" with over 22.000 calls. That seems a lot! In the second half, many, maybe all, onMeasure()-methods of the views and layouts are called.
What I tried:
I filled every textview with static dummy values in the adapter and excluded the part with loading the images. It changes nothing, traceview shows the same picture.
In the second try, I looked at the LinearLayout of my list item and replaced every "wrap_content" I found with "match_parent" - nothing. Still the same.
I am still open for your thoughts and hints. :)
You have no control over when and how frequently getView() is called.
If it really takes 500ms for you to generate 8 row Views, then there is something wrong with your code. You can use Traceview to determine specifically where you are taking the time, so you can attempt to do something to improve performance (e.g., caching).

why does getCheckedItemPositions() return null when there are more than 7 items in a multiple choice list?

I am starting to learn Android Development and I had a question about multiple choice lists. I have a list in my layout with about 20 items with an ArrayAdapter wrapped around a string array. When I try to use myList.getCheckedItemPositions() with all the 20 items, it returns a null pointer but when I reduce the number of items to 6, I am able to find which items are checked and display them too (in other words, it works as expected).
I have a subclass that implements the AdapterView.OnItemClickListener interface and I have supplied an instance of the class to myList.SetOnIntemClickListener(). In the subclass, I have the implemented method, onItemClick() where I call myList.getCheckedItemPositions() and iterate through the checked items to display them.
When I tried debugging the application, the ListView only had 12 children, the last 5 being null, which meant that only 7 of the 20-some items that the ArrayAdapter was supplying were being "read". Please help me figure out what I am doing wrong in this, do I have to use a different listener for a multiple choice list? Also the ListView is displayed in a way that only the first 5 items from the list are displayed, would that have anything to do with this?
Thanks
Have you set the list view choice mode to multiple?

Categories

Resources