zoukankan      html  css  js  c++  java
  • 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()



  • 相关阅读:
    mysql 性能优化方案
    MYSQL 优化常用方法
    MongoDB集群架构及搭建
    memcache分布式 [一致性hash算法] 的php实现
    memcache 的内存管理介绍和 php实现memcache一致性哈希分布式算法
    【转】linux 查看进程启动路径
    centos7 编译安装nginx+tcp+grpc转发
    mongodb笔记
    【转】mysql 解事务锁
    【转】centos7 搭建etcd集群
  • 原文地址:https://www.cnblogs.com/ameryzhu/p/6555627.html
Copyright © 2011-2022 走看看