Faiz Anwar
Faiz Anwar

Reputation: 658

Getting wrong position in custom ListView while scrolling

I am getting wrong position in custom ListView while scrolling.

I have tried the ViewHolder pattern and an ArrayAdapter but both giving the same problem.

If I reproduce the code using Java then I am getting the proper position while scrolling.

So is it Xamarin architecture bug ?

Below is my sample code:

Activity Class

namespace ArrayAdapterDemoApp
{
    [Activity(Label = "ArrayAdapterDemoApp", MainLauncher = true, 
    Icon ="@drawable/icon")]
    public class MainActivity : Activity
    {
        private static List<DataBean> _ItemsList = new List<DataBean>();
        private static CustomAdapter _adapter;
        private ListView _listview;

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

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            _listview = FindViewById<ListView>(Resource.Id.mylist);
            DataBean obj1 = new DataBean();
            obj1.Name = "AA";
            obj1.City = "11";
            _ItemsList.Add(obj1);

            DataBean obj2 = new DataBean();
            obj2.Name = "BB";
            obj2.City = "22";
            _ItemsList.Add(obj2);

            DataBean obj3 = new DataBean();
            obj3.Name = "CC";
            obj3.City = "33";
            _ItemsList.Add(obj3);

            ...

            DataBean obj15 = new DataBean();
            obj15.Name = "OO";
            obj15.City = "1010";
            _ItemsList.Add(obj15);

            _adapter = new CustomAdapter(this, _ItemsList);
            _listview.Adapter = _adapter;
        }
    }
}

Custom Adapter

namespace ArrayAdapterDemoApp
{
    public class CustomAdapter : ArrayAdapter<DataBean> 
    {
        private class TaskViewHolder : Java.Lang.Object
        {
            public TextView tvName;
            public TextView tvCity;
        }

        List<DataBean> listData;
        Activity _context;
        int _position;

        public CustomAdapter(Activity context, List<DataBean> dataList)
            : base(context, Resource.Layout.adapter_row, dataList)
        {
            this._context = context;
            this.listData = dataList;
        }

        public override long GetItemId(int position)
        {
            return position;
        }

        public override int Count
        {
            get { return listData.Count; }
        }

        //With View Holder
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            DataBean data = listData[position];
            TaskViewHolder viewHolder= null; // view lookup cache stored in tag
            if (convertView == null)
            {
                viewHolder = new TaskViewHolder();
                LayoutInflater inflater = LayoutInflater.From(_context);
                convertView = inflater.Inflate(Resource.Layout.adapter_row, parent, false);

                viewHolder.tvName = convertView.FindViewById<TextView>(Resource.Id.text1);
                viewHolder.tvCity = convertView.FindViewById<TextView>(Resource.Id.text2);


                convertView.Tag = viewHolder;
            }

            if(viewHolder==null)
            {
                viewHolder = (TaskViewHolder)convertView.Tag;
            }

            viewHolder.tvName.Text = data.Name;
            viewHolder.tvCity.Text = data.City;

            return convertView;
        }
    }
}

DataBean Class

namespace ArrayAdapterDemoApp
{
    public class DataBean
    {
        public string Name { get; set; }
        public string City { get; set; }
    }
}

Upvotes: 0

Views: 1583

Answers (3)

Suchith
Suchith

Reputation: 1527

You can tag the position of each row to the control to get the correct position or Another method is by using action event binding to each view row. This also solves duplicate method call issue. this might be helpful: http://appliedcodelog.blogspot.in/2015/07/working-on-issues-with-listview-in.html#WrongPosition

Upvotes: 0

Vivek  Samele
Vivek Samele

Reputation: 349

I had also same issue so I resolved it by just Tag the position to the view.for example.

//iv_delete is a imageview

holder.iv_delete.Tag = position;

and get the position from the Tag

For me it was like that int finalPosition = (Integer)holder.iv_delete.Tag.IntValue();

Enjoy!!!!!

Upvotes: 2

Stam
Stam

Reputation: 2490

Add in your adapter class this method:

  public DataBean GetItemAtPosition(int position)
  {
       return this.listData[position];
  }

Upvotes: 0

Related Questions