了解ViewHolder模式 [英] Understanding the ViewHolder pattern

查看:102
本文介绍了了解ViewHolder模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为具有两种类型的行的ListView创建了一个适配器. ListView有4行.最后一行的布局不同,这就是为什么我在getview中使用GetItemViewType方法

I created an adapter for a ListView which has two types of rows. The ListView has 4 rows. The last row has a different layout, that's why i use the GetItemViewType method in getview

我正在尝试了解模式的工作原理.我看了这个: https://www.youtube.com/watch?v=bWsWe9T9HJw 以获得更好的对此事的认知 回收工作原理

I'm trying to understand how the pattern works. I watched this: https://www.youtube.com/watch?v=bWsWe9T9HJw to get a better understanding of how recycling works

我不明白的是:当我在列表视图中向下滚动时,convertview 始终为null.当我再次向上滚动时,convertview不是null且可重复使用.

What i don't understand is: when i scroll down in my listview, the convertview is always null. When i scroll back up again, the convertview is not null and is reusable.

convertview是否仅对于列表中的第一项不为null?我不明白为什么 每个新商品都为空吗?

Shouldn't convertview be null only for the first item in the list? i don't get why it is null for each new item?

public override View GetView (int position, View convertView, ViewGroup parent)
    {
        BaseBundelVO bundle = _bundles [position];

        DSBundleListItem bundleHolder = null;
        DSBundleArchiveItem archiveHolder = null;

        int type = GetItemViewType(position);
        if (convertView == null)
        {
            bundleHolder = new DSBundleListItem (_activity);
            archiveHolder = new DSBundleArchiveItem (_activity);

            switch (type) 
            {
            case 0:
                convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleListItem, null);
                bundleHolder.IconIv = convertView.FindViewById<ImageView> (Resource.Id.iconIv);
                bundleHolder.CoverIv = convertView.FindViewById<ImageView> (Resource.Id.coverIv);
                bundleHolder.CoverTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverTitleTv);
                bundleHolder.CoverSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverSubTitleTv);
                bundleHolder.BundleProgress = convertView.FindViewById<ProgressBar> (Resource.Id.bundleProgress);
                convertView.Tag = bundleHolder;
                break;
            case 1:
                convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleArchiveItem, null);
                archiveHolder.ArchiveTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveTitleTv);
                archiveHolder.ArchiveSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveSubTitleTv);
                convertView.Tag = archiveHolder;
                break;
            }

        } 
        else 
        {
            switch (type) 
            {
            case 0:
                bundleHolder = (DSBundleListItem)convertView.Tag;
                Console.WriteLine (bundleHolder.IsDisposed ());
                bundleHolder.RemoveImageLoaderCallBack ();
            break;
            case 1:
                archiveHolder = (DSBundleArchiveItem)convertView.Tag;
                Console.WriteLine (archiveHolder.IsDisposed ());
                archiveHolder.RemoveImageLoaderCallBack ();
            break;
            }
        }

        switch (type) 
        {
        case 0:
            bundleHolder.CoverTitleTv.Text = bundle.Title;
            bundleHolder.CoverSubTitleTv.Text = bundle.SubTitle;
            bundleHolder.LoadImage(bundle.CoverImageLocation,bundle.Icon);
            break;
        case 1:
            archiveHolder.ArchiveTitleTv.Text    = "Archief";
            archiveHolder.ArchiveSubTitleTv.Text = "Bekijk onze eerder verschenen publicaties";
            break;
        }

        return convertView;
    }

推荐答案

convertview是否仅对于列表中的第一项不为null?

Shouldn't convertview be null only for the first item in the list?

通常不会.

让我们假设ListView中有8行可见.这意味着ListView将使用null作为convertView参数调用getView()至少8次,以填充ListView中的可见空间.

Let's suppose that that 8 rows are visible in the ListView. That means the ListView will call getView() at least 8 times with null for the convertView parameter, to populate the visible space in the ListView.

ListView可能还会缓存一些其他行,以便能够快速响应滚动事件,作为缓存.

ListView may also cache a few additional rows, to be able to rapidly respond to scrolling events, as a cache.

此外,对于您而言,每种视图类型都维护有单独的对象池.

Plus, in your case, there are separate object pools maintained for each view type.

但是,如果适配器中有足够的东西,最终即使在最初向下滚动时,您也将循环使用.这完全取决于行的大小,适配器从getCount()返回的值,等等.

If your adapter has enough stuff in it, though, eventually you will recycle even during the initial scroll down. It all depends on the size of the rows, the values that the adapter returns from getCount(), etc.

请注意,这与视图持有者模式完全无关.

And note that this has nothing really to do with the view holder pattern.

这篇关于了解ViewHolder模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆