Adapter Class Cast Exception Removing Footer View from ListView

又好久没写blog了,工作的时候,解决了一些问题,却又觉得时间紧,没空写。习惯需要坚持啊。

今天在做ListView滚动自动加载的时候碰到了Adapter Class Cast Exception Removing Footer View from ListView 问题。


感到很奇怪,怎么会出类型转换错误呢?以前用的时候怎么没碰到?我最开始在想是不是因为此时还没有给listview添加footerview。

但是这也不对啊,那样只会报Null Pointer Exception,看了一下remove的源码:

 public boolean removeFooterView(View v) {
        if (mFooterViewInfos.size() > 0) {
            boolean result = false;
            if (mAdapter != null && ((HeaderViewListAdapter) mAdapter).removeFooter(v)) {
                if (mDataSetObserver != null) {
                    mDataSetObserver.onChanged();
                }
                result = true;
            }
            removeFixedViewInfo(v, mFooterViewInfos);
            return result;
        }
        return false;
    }

系统已经帮我判断了footerview的数量,大于0才会去remove。


于是我又开始猜想,adapter的类型转换异常难道是加了FooterView和没有加FooterView的适配器是不一样的吗?那这个adapter会在哪儿初始化呢?

应该是在listview初始化的时候,于是去打算去看看ListView的setAdapter方法:

public void setAdapter(ListAdapter adapter) {
        if (mAdapter != null && mDataSetObserver != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }

        resetList();
        mRecycler.clear();

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

        mOldSelectedPosition = INVALID_POSITION;
        mOldSelectedRowId = INVALID_ROW_ID;

        // AbsListView#setAdapter will update choice mode states.
        super.setAdapter(adapter);

        if (mAdapter != null) {
            mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
            checkFocus();

            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

            mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());

            int position;
            if (mStackFromBottom) {
                position = lookForSelectablePosition(mItemCount - 1, false);
            } else {
                position = lookForSelectablePosition(0, true);
            }
            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);

            if (mItemCount == 0) {
                // Nothing selected
                checkSelectionChanged();
            }
        } else {
            mAreAllItemsSelectable = true;
            checkFocus();
            // Nothing selected
            checkSelectionChanged();
        }

        requestLayout();
    }

终于找到原因了,在HeaderView或者FooterView不为空的情况下,会把当前传入的adapter转换为HeaderViewListAdapter。否则会用原有的adapter。

So, the conclusion:

如果出现了Adapter Class Cast Exception Removing Footer View from ListView ,要在调用listview.setAdapter(myadapter);之前,加上addFooterView()或者addHeaderView()



原文地址:https://www.cnblogs.com/ameryzhu/p/6555627.html