ListView ViewHolder 组件返回 null Android

ListView ViewHolder components returning null Android

我已经为我的 Listview 实现了 ViewHolder 模式,如下所示:-

    public class HomeListAdapter : BaseAdapter
    {

        public HomeListAdapter(List<Models.MyModel> myList, Activities.HomeActivity homeActivity)
        {
            // TODO: Complete member initialization
            this.myList = myList;
            this.homeActivity = homeActivity;
            prefs = PreferenceManager.GetDefaultSharedPreferences(homeActivity);

            inflater = LayoutInflater.FromContext(homeActivity);

        }
        public override int Count
        {
            get { return myList.Count; }
        }
        public override int ViewTypeCount
        {
            get
            {
                return 2;
            }
        }

        public override Java.Lang.Object GetItem(int position)
        {
            return position;
        }



        public override long GetItemId(int position)
        {
            return 0;
        }
        public override int GetItemViewType(int position)
        {
            if (position == 0 || position == 1)
            {
                return 1;
            }
            else
            {
                return 2;
            }
        }
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View rootView = convertView;
            MyViewHolder mHolder;
            var mData = myList[position];

            int item = GetItemViewType(position);   
            if(rootView ==null)
            {
                mHolder = new MyViewHolder(); ;
                switch(item)
                {
                    case 1:
                        rootView = homeActivity.LayoutInflater.Inflate(Resource.Layout.phone_home_big_row2, null);
                        mHolder.txtDate = convertView.FindViewById<TextView>(Resource.Id.txtDate);
                         mHolder.txtTitle = convertView.FindViewById<TextView>(Resource.Id.txtTitle);

                         mHolder.txtDetail = convertView.FindViewById<TextView>(Resource.Id.txtDetail);
                         mHolder.imgPlaceholderImage = convertView.FindViewById<ImageView>(Resource.Id.imgPlaceholderImage);
                         mHolder.txtCategory = convertView.FindViewById<TextView>(Resource.Id.txtCategory);
                        break;
                    case 2:
                        rootView = homeActivity.LayoutInflater.Inflate(Resource.Layout.phone_home_list_row, null);
                        mHolder.txtTitle = convertView.FindViewById<TextView>(Resource.Id.txtTitle);
                        mHolder.txtDate = convertView.FindViewById<TextView>(Resource.Id.txtDate);
                        mHolder.viewColor = convertView.FindViewById<View>(Resource.Id.viewColor);
                        mHolder.imgPlaceholderImage = convertView.FindViewById<ImageView>(Resource.Id.imgPlaceholderImage);
                        break;
                }

                rootView.Tag = mHolder;
            }
            else
            {
                mHolder = (MyViewHolder)rootView.Tag;
            }

           switch(item)
           {
               case 1:
                     mHolder.txtTitle.Text = mData.Title;
            if (mHolder.txtDetail != null)
            {
                mHolder.txtDetail.Text = mData.BodyText;
                mHolder.txtDetail.Ellipsize = TextUtils.TruncateAt.End;
                mHolder.txtDetail.SetMaxLines(3);
                mHolder.txtDetail.SetTextColor(Color.Black);
            }
            if (mHolder.txtCategory != null)
            {
                mHolder.txtCategory.Text = mData.NewsSourceTitle;
                mHolder.txtCategory.SetTextColor(Color.White);

                mHolder.txtCategory.SetBackgroundColor(Color.ParseColor(mData.Color));
            }
            if (!string.IsNullOrEmpty(mData.PublishedDate))
            {
                mHolder.txtDate.Text = DateTime.Parse(mData.PublishedDate).ToString("dd MMMM yyyy", CultureInfo.InvariantCulture);
            }

                   break;
               case 2:
                   mHolder.txtTitle.Text = mData.Title;

                   if (mHolder.viewColor != null)
                   {
                       mHolder.viewColor.SetBackgroundColor(Color.ParseColor(mData.Color));
                   }
                    if (!string.IsNullOrEmpty(mData.PublishedDate))
                   {
                      mHolder.txtDate.Text = DateTime.Parse(mData.PublishedDate).ToString("dd MMMM yyyy", CultureInfo.InvariantCulture);
                    }


                   break;

           }






            return rootView;
        }
        public class MyViewHolder : Java.Lang.Object
        {

            public TextView txtTitle { get; set;}
            public TextView txtDate{ get; set;}
            public TextView txtDetail{ get; set;}
            public ImageView imgPlaceholderImage { get; set; }
            public View viewColor { get; set; }
            public TextView txtCategory { get; set; }
        }
    }
}

但我总是 mHolder.txtTitle 并且其他组件为 null,即使 mHolder 不为 null。我需要根据它们 positions.Is 来膨胀两种不同的布局 我做错了什么?任何帮助表示赞赏。谢谢

首先,您应该 return getItem 覆盖方法中特定位置的项目

public override Java.Lang.Object GetItem(int position)
    {
        return myList(position);
    }

出现您的问题是因为您的代码有时引用 rootView,有时引用 convertView

在这一行中,您在 convertView 上执行 findViewByID():

mHolder.txtTitle=convertView.FindViewById<TextView>(Resource.Id.txtTitle);

但是,您从未检查过 convertView 是否为空,如果是则为其分配新的 View。相反,您创建了一个对 convertView 的新引用,您将其称为 rootView,检查 that 是否为 null,如果是,则您分配了一个新的 ViewrootView。因此,rootView 现在是非空的,但 convertView 仍然是。

public override View GetView(int position,View convertView,ViewGroup parent)
    {
    View rootView=convertView;
    //...
    if(rootView==null)
    {
      mHolder=new MyViewHolder();;
      switch(item)
      {
        case 1:
          rootView = homeActivity.LayoutInflater.Inflate(Resource.Layout.phone_home_big_row2,null);
          mHolder.txtDate=convertView.FindViewById<TextView>(Resource.Id.txtDate); 
                        // ^^^^^^^^^^ convertView can still be null!!!
          //...
      }

我建议您删除代码中对 rootView 的所有引用,直接使用 convertView。这就是将它提供给您的方法的原因。