简体   繁体   English

ListView ViewHolder组件返回空Android

[英]ListView ViewHolder components returning null Android

I have implemented the ViewHolder pattern for my Listview like so:- 我已经为我的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; }
        }
    }
}

But i always mHolder.txtTitle and the other components as null, even if the mHolder is not null. 但是我总是将mHolder.txtTitle和其他组件设置为null,即使mHolder不为null。 I need to inflate two different layouts depending upon their positions.Is there something wrong I am doing? 我需要根据其位置给两个不同的布局充气。我在做错什么吗? Any help is appreciated. 任何帮助表示赞赏。 Thanks. 谢谢。

First of all you should return items in particular position from the getItem overrided method 首先,您应该从getItem重写方法返回特定位置的项目

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

Your issue is arising because your code sometimes refers to rootView and sometimes to convertView . 之所以出现问题,是因为您的代码有时引用了rootView ,有时引用了convertView

In this line, you perform findViewByID() on convertView : 在这一行中,您对convertView执行findViewByID()

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

However, you never checked if convertView is null and assigned it a new View if it is. 但是,您从未检查过convertView是否为null,也没有为其分配新的View Instead, you created a new reference to convertView , which you called rootView , check if that was null, and if it was, then you assigned a new View to rootView . 相反,你创建了一个新的参考convertView ,你叫rootView ,检查,如果是空的,如果是,那么你分配一个新的ViewrootView。 thus, rootView now is non-null, but convertView still is. 因此, rootView现在为非null,但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!!!
          //...
      }

I suggest you remove all references to rootView in your code and just work with convertView directly. 我建议您在代码中删除对rootView所有引用, rootView直接使用convertView that's why it's provided to your method. 这就是将其提供给您的方法的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM