ListView ViewHolder组件返回null Android

时间:2016-02-13 04:43:13

标签: android listview android-viewholder

我已经为我的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。我需要根据他们的位置来扩充两种不同的布局。我有什么问题吗?任何帮助表示赞赏。感谢。

2 个答案:

答案 0 :(得分:0)

首先,您应该从getItem重写方法返回特定位置的项目

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

答案 1 :(得分:0)

您的问题正在发生,因为您的代码有时会引用rootView,有时引用convertView

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

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

但是,您从未检查过convertView是否为空,如果是,则为其分配了新的View。相反,您创建了一个对convertView的新引用,您调用了rootView,检查 是否为空,如果是,则为您分配了新View } rootView 。因此,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。这就是为什么它提供给你的方法。

相关问题