Search code examples
xamarin.androidnotifydatasetchanged

NotifyDataSetChanged not working xamarin.android


for example list has rows with ages

On searching 45 you get the result filtered as 45. but clicking on it results on showing age from 1. it is like the position does not change for the ages but uses the original ArrayList adapter position.

my code is as below,

 public class MainActivity : Activity
{
    private List<Friend> mFriends;
    private ListView mListView;
    private EditText mSearch;
    private LinearLayout mContainer;
    private bool mAnimatedDown;
    private bool mIsAnimating;
    private FriendsAdapter mAdapter;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);
        mListView = FindViewById<ListView>(Resource.Id.listView);
        mSearch = FindViewById<EditText>(Resource.Id.etSearch);
        mContainer = FindViewById<LinearLayout>(Resource.Id.llContainer);

        mSearch.Alpha = 0;
        mSearch.TextChanged += mSearch_TextChanged;

        mFriends = new List<Friend>();
        mFriends.Add(new Friend { FirstName = "Bob", LastName = "Smith", Age = "33", Gender = "Male" });
        mFriends.Add(new Friend { FirstName = "Tom", LastName = "Smith", Age = "45", Gender = "Male" });
        mFriends.Add(new Friend { FirstName = "Julie", LastName = "Smith", Age = "2020", Gender = "Unknown" });
        mFriends.Add(new Friend { FirstName = "Molly", LastName = "Smith", Age = "21", Gender = "Female" });
        mFriends.Add(new Friend { FirstName = "Joe", LastName = "Lopez", Age = "22", Gender = "Male" });
        mFriends.Add(new Friend { FirstName = "Ruth", LastName = "White", Age = "81", Gender = "Female" });
        mFriends.Add(new Friend { FirstName = "Sally", LastName = "Johnson", Age = "54", Gender = "Female" });

        mAdapter = new FriendsAdapter(this, Resource.Layout.row_friend, mFriends);
        mListView.Adapter = mAdapter;


        mListView.ItemClick += MListView_ItemClick;
    }

    private void MListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        var friend = mFriends[e.Position];


        Toast.MakeText(this, friend.Age, ToastLength.Short).Show();
    }

    void mSearch_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
    {

        List<Friend> searchedFriends = (from friend in mFriends
                                        where friend.FirstName.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase) || friend.LastName.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase)
                                        || friend.Age.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase) || friend.Gender.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase)
                                        select friend).ToList<Friend>();

        mAdapter = new FriendsAdapter(this, Resource.Layout.row_friend, searchedFriends);
        mListView.Adapter = mAdapter;
        mAdapter.NotifyDataSetChanged();


    }

im working this examples >>Xamarin 15 - Searching a Listview using LINQ


Solution

  • On searching 45 you get the result filtered as 45. but clicking on it results on showing age from 1.

    There is no problem with that code and since you've reset the adapter for mListView, you don't need to add code like mAdapter.NotifyDataSetChanged(); here, it's totally a new adapter, the NotifyDataSetChanged works when data in that adapter changes.

    So the real cause of your problem is that you used code var friend = mFriends[e.Position];, you used clicked position in the ListView to find the friend in mFriends list. The position is set when you add data to this list, but what you need is to find friend in searchedFriends after querying.

    For example:

    private List<Friend> searchedFriends;
    private void MListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        Friend friend;
        if(searchedFriends == null || searchedFriends.Count == mFriends.Count)
        {
            friend = mFriends[e.Position];
        }
        else
        {
            friend = searchedFriends[e.Position];
        }
    
        Toast.MakeText(this, friend.Age, ToastLength.Short).Show();
    }
    
    void mSearch_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
    {
    
        searchedFriends = (from friend in mFriends
                                        where friend.FirstName.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase) || friend.LastName.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase)
                                        || friend.Age.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase) || friend.Gender.Contains(mSearch.Text, StringComparison.OrdinalIgnoreCase)
                                        select friend).ToList<Friend>();
    
    
        mAdapter = new FriendsAdapter(this, Resource.Layout.row_friend, searchedFriends);
        mListView.Adapter = mAdapter;
    }