views:

468

answers:

3

I'm having the following problem:

I have a ListActivity, its ListView is composed by an icon, text and a checkbox (using LayoutInflater).

The Adapter for the ListView extends ResourceCursorAdapter (i.e. the data source of the ListView is retrieved from a database, also the Checked status of each row)

Everything works pretty Ok, except when I uncheck/check the checkbox in any row, if I scroll down until the modified checkbox is no longer visible, and then scroll up, the checkbox is restored to its original state.

The database IS modified, this is not the problem (i.e. if I modify a row and exit the activity, and enter again, the modified row is displayed Ok).

My guess is that this has something to do on how the list is rendered because for some reason the ListView "renders" the original state of all rows when it was first populated when scrolling.

I've been looking around for this bug but I don't find anybody that had this problem. I appreciate any advice you have.

A: 

When the item comes into view, your ListAdapter.getView() method will be invoked.

This could happen multiple times per session, if for instance you scroll the item off the screen and then on again.

I would suggest you put a breakpoint on getView() and run the app with the debugger. Repeat your test, and on the occasion getView() is invoked for the second time, check the logic where your checkbox is set up.

Another consideration is that the second parameter of getView is a 'convertView' View. This is one of your own Views from other list entries that is no longer visible. The OS is returning this view to you so that you have the option of 'recycling' the view to make the new entry, rather than inflating a new one which will have a performance impact.

If you are ignoring this parameter, it won't be a problem (although to make a smooth scrolling list you may consider using it in the future - just remember to check the View is of the type you expect by setting the Tag).

If you are choosing to use this parameter to attempt a view recycle, check your logic, and ensure you are setting all controls to the desired state as the layout default state may not apply.

Jim Blackler
Thanks for the reply.As I understand, for a CursorAdapter I should modify the contents of the View in the bindView method.I'm not sure if getView is used in this case. Or in any case, when will bindView will be called and when getView?Right now I'm not using at all getView, just newView and bindView. I researched a little bit about the getView and the use of convertView for recycling the view but I'm still confused of when the bindView will be called (getView and bindView would have the same code?)Also, bindView does not pass the convertView but just A view.
adrianrdzv
A: 

This link provides an insight into your problem

http://efreedom.com/Question/1-3036296/EditText-items-in-a-scrolling-list-lose-their-changes-when-scrolled-off-the-screen

List rows get recycled. Your Cursor may have 1,000 records, but there are not going to be 1,000 EditText widgets created if you scroll through the list. Rather, there will be 10 or so, depending on how many rows are simultaneously visible. Rows get recycled, and the binding operation will replace the old EditText value with a new value from the Cursor for whatever row just scrolled onto the screen, replacing whatever was there before (previous value from the database or a user-edited value).

Muniu
A: 

The problem was solved by closing the corresponding cursor after modifying the database and open it again with changeCursor().

adrianrdzv