On Aug 7, 2012, at 7:08 PM, Steven Pack <steven_john_p...@yahoo.com.au> wrote:
> OK, last thing. When I delete the item, I want the listview to update and NOT 
> scroll to the top. Recreating the adapter with the now updated list updates 
> the view, but scrolls to the top (and is inefficient). All the SO articles 
> and docco say to use ArrayAdapter<T>.NotifyDataSetChanged(). I find that 
> method doesn't work as I expect though:
> 
> I can do along the lines of (sorry not on the coding computer):
> 
> lvHeadwords.Adapter = new MyCustomAdapterHeadwords(Headwords); //which 
> inherits ArrayAdapter<T>
> 
> //Then in response to a delete click....
> Headwords.RemoveAt(position)
> (((MyCustomAdapterHeadwords)lvHeadwords.Adapter).NotifyDataSetChanged();
> Assert.AreEqual(lvHeadwords.Adapter.Count, Headwords.Count); //Boom, they're 
> not.... and the UI hasn't updated
> 
> That's supposed to work right?

In theory, yes. For you, apparently not. ;-)

Without a test case, all I can do is guess; I just have lots of guesses. :-)

In this case, here's what I know: the Java ArrayAdapter type has it's own List:

        
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/ArrayAdapter.java#L48

Specifically, ArrayAdapter.add(), ArrayAdapter.insert(), and (most importantly) 
ArrayAdapter.getCount() all use this internal list.

AdapterView, meanwhile, uses ArrayAdapter.getCount() to tell if anything has 
changed (search for getCount() and getItem()):

        
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/AdapterView.java

_Your_ adapter, however, doesn't override the Count property (see 
ListActivityRowArrayAdapter):

        http://lists.ximian.com/pipermail/monodroid/2012-August/011679.html

Result: Sure, you've modified _your_ list, but Android (1) doesn't see a change 
in count, and (2) doesn't see your new values.

There are three possible solutions that I see:

(1) Don't inherit ArrayAdapter<T>, inherit from BaseAdapter<T>. This will force 
you to implement the full abstraction, specifically the Count property, 
GetItem() method (i.e. the indexer), and the GetItemId() methods.

(2) Override the other ArrayAdapter<T> methods so that Android uses _your_ 
state, not the "duplicate" Java state. At minimum you'd need to override the 
Count property, you might want to consider overriding the HasStableIds and 
IsEmpty properties, and if you expect/require Java to call your Add() method, 
you'll need to override Add()/AddAll()/Insert()/etc. as well.

I suspect all you'll really need to do is override the Count property, though 
(1) would be better imho.

(3) Move your collection into Java, by using ArrayAdapter<T>.Add()/etc. instead 
of using a List<Headword> member. This isn't ideal, as each member you add will 
take out a gref (ouch).

 - Jon

_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to