• ListView-添加head跟foot item 问题


    今天在使用ListView 的 addFooterView 的方法时候,遇到了一个问题。当我代码中执行了如下的操作

    ListView listView = new ListView(this);
    listView.addFooterView(mItem);
    listview.setAdapter(mAdapter);
    listview.getAdapter();

    得到的adapter一直报错,说是类转化错误。后来通过看ListView源码发现了问题所在。

    我们看一下addFooterView方法

     public void addFooterView(View v, Object data, boolean isSelectable) {
            final FixedViewInfo info = new FixedViewInfo();
            info.view = v; 
            info.data = data;
            info.isSelectable = isSelectable;
            mFooterViewInfos.add(info);
            mAreAllItemsSelectable &= isSelectable;
    
            // Wrap the adapter if it wasn't already wrapped.
            if (mAdapter != null) {
                if (!(mAdapter instanceof HeaderViewListAdapter)) {
                    mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
                }    
    
                // In the case of re-adding a footer view, or adding one later on,
                // we need to notify the observer.
                if (mDataSetObserver != null) {
                    mDataSetObserver.onChanged();
                }    
            }    
        }    

    我们看到当我们使用这个方法的时候,其他会把adapter重新创建成为HeaderViewListAdapter,当我们再次得到adapter的时候,它其实已经不是你set 进去的adapter了

    网上有好多人说,我们只需要在listview.setAdapter()方法之前使用addFooter方法就可以避免这个问题。我尝试了这种方法,结果还是一样的结果。也就是说,无论你在setAdapter()前后使用这个方法

    ,对adapter的影响都是一样的,因为我们通过看ListView的setAdapter方法就知道原因了

            if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
                mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
            } else {
                mAdapter = adapter;
            }

    我们看到setAdapter里面有上面这句代码。这就说明了,我们无论在哪里使用addFooter方法,其实都会更改adapter

    现在我们可以在看看,HeaderViewListAdapter是一个什么东西

    public class HeaderViewListAdapter implements WrapperListAdapter, Filterable {
    
        private final ListAdapter mAdapter;
    
        // These two ArrayList are assumed to NOT be null.
        // They are indeed created when declared in ListView and then shared.
        ArrayList<ListView.FixedViewInfo> mHeaderViewInfos;
        ArrayList<ListView.FixedViewInfo> mFooterViewInfos;
    。。。。。。。。。。。。。。。。

    它其实也是一个adapter,只不过它里面保存了listview的adapter跟head、foot信息。这样,如果我们想得到当初我们赋给listview的adapter的话,可以考虑从它里面得到。

    另外一点需要注意,当我们通过listview.getAdapter()得到adapter的时候,然后通过adapter.getCount的方法得到的item数,是包含了head跟foot的。看下HeaderViewListAdapter 中

    getcount方法

        public int getCount() {
            if (mAdapter != null) {
                return getFootersCount() + getHeadersCount() + mAdapter.getCount(); 
            } else {
                return getFootersCount() + getHeadersCount();
            }
        } 

    如果我们想要使用listview.getAdapter()得到我们当初传入的纯净adapter,可以使用如下方法

                        Adapter a =  listView.getAdapter();
                        ConversationListAdapter adapter = null;
                        if (a instanceof HeaderViewListAdapter) {
                            adapter = (ConversationListAdapter) ((HeaderViewListAdapter) a).getWrappedAdapter();
                        } else if (a instanceof ConversationListAdapter) {
                            adapter = (ConversationListAdapter) a;
                        } else {
                            android.util.Log.e("zhangshuli", "a=="+a);
                        }    

    也就是通过instanceof方法,判断我们得到的adapter是原来的,还是被listview改造过的。其中getWrappedAdapter是HeaderViewListAdapter提供的方法,获得的就是纯净adapter

  • 相关阅读:
    ZOJ 3713 In 7-bit (题意不好理解,十进制、二进制、十六进制的转换问题)
    C++ cout 如何保留小数输出
    ZOJ 3705 Applications 模拟
    Google Code Jam Round 1A 2015 Problem B. Haircut 二分
    --算法分析与设计--课程作业--【顺序统计】--【采用链表法散列表】--【开放地址法(双重散列)】
    C++获取当前时间和计算程序运行时间的方法
    【STL__set_的应用】
    ZOJ 3601 Unrequited Love 【STL__pair_的应用】
    Linux概念
    fragment创建
  • 原文地址:https://www.cnblogs.com/zhangshuli-1989/p/zhangshuli_footitem_15731184.html
Copyright © 2020-2023  润新知