kaielx
kaielx

Reputation: 49

Xamarin Android Custom Listview Error

In my custom listview, I keep getting System.NullReferenceException: Object reference not set to an instance of an object. on that viewholder.item = item

Completely at a loss here as to why this is happening.

   public class CustomProductViewAdapter : BaseAdapter<ProductTableItem>
{
    void MoreInfo_Click(object sender, System.EventArgs e)
    {
        var item = ((sender as View).Tag as ViewHolderItem).Item;
        Log.Debug("TAG", item.ProdName);
        var itemString = string.Format($"{item.ProdkeyID_str} : {item.ProdName} : {item.ProdPrice}");
        new AlertDialog.Builder(context).SetMessage(itemString).Create().Show();
    }

    public class ViewHolderItem : Java.Lang.Object
    {
        public ProductTableItem Item;
    }

    readonly List<ProductTableItem> items;
    readonly Activity context;

    public CustomProductViewAdapter(Activity context, List<ProductTableItem> items)
    {
        this.context = context;
        this.items = items;
    }

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

    public override ProductTableItem this[int position]
    {
        get { return items[position]; }
    }

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

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        var view = convertView;
        var item = items[position];
        ViewHolderItem viewHolder = null;
        if (view == null)
        {
            viewHolder = new ViewHolderItem
            {
                Item = item
            };
            view = context.LayoutInflater.Inflate(Resource.Layout.invoicing_sales_product_listview, null);
            var moreInfo = view.FindViewById<ImageView>(Resource.Id.more_info);
            moreInfo.Tag = viewHolder;
            moreInfo.Click += MoreInfo_Click;
        }
        var moreInfo2 = view.FindViewById<ImageView>(Resource.Id.more_info);
        viewHolder = moreInfo2.Tag as ViewHolderItem;
        viewHolder.Item = item;
        view.FindViewById<TextView>(Resource.Id.product_name).Text = item.ProdName;
        view.FindViewById<TextView>(Resource.Id.product_mrpvalue).Text = item.ProdPrice;
        view.FindViewById<TextView>(Resource.Id.product_bbvalue).Text = item.ProdPrice2;
        view.FindViewById<TextView>(Resource.Id.product_savingsvalue).Text = "extra info";
        view.FindViewById<TextView>(Resource.Id.product_value).Text = "More info";

        return view;
    }
}

}

Upvotes: 1

Views: 222

Answers (1)

pinedax
pinedax

Reputation: 9346

You should take tour ViewHolderItem intitialization out of the if that validates if the View is null and simplify a little your code.

public override View GetView(int position, View convertView, ViewGroup parent)
{
    var view = convertView ?? context.LayoutInflater.Inflate(Resource.Layout.invoicing_sales_product_listview, null);

    var item = items[position];
    ViewHolderItem viewHolder = new ViewHolderItem
    {
        Item = item
    };

    var moreInfo = view.FindViewById<ImageView>(Resource.Id.more_info);
    moreInfo.Tag = viewHolder;
    moreInfo.Click += MoreInfo_Click;

    var moreInfo2 = view.FindViewById<ImageView>(Resource.Id.more_info);
    viewHolder = moreInfo2.Tag as ViewHolderItem;
    viewHolder.Item = item;
    view.FindViewById<TextView>(Resource.Id.product_name).Text = item.ProdName;
    view.FindViewById<TextView>(Resource.Id.product_mrpvalue).Text = item.ProdPrice;
    view.FindViewById<TextView>(Resource.Id.product_bbvalue).Text = item.ProdPrice2;
    view.FindViewById<TextView>(Resource.Id.product_savingsvalue).Text = "extra info";
    view.FindViewById<TextView>(Resource.Id.product_value).Text = "More info";

    return view;
}

The if(view == null) is not longer necessary as you are making sure you always have a view instance with the first line of the method.

You don't need to set the viewHolder as null and then create the instance.

Hope this works.

Upvotes: 1

Related Questions