ListView在removeFooterView时报java.lang.ClassCastException错问题

本文探讨了在使用ListView时遇到的Java.lang.ClassCastException异常问题及其原因,深入解析了HeaderViewListAdapter类的作用与使用方法,解释了为何在未正确设置header或footer时会出现异常,并通过代码示例详细说明了ListView的内部机制。
摘要由CSDN通过智能技术生成

自古英雄不问出处,奈何我却不是英雄!

转载请标明出处:http://blog.csdn.net/u011275767/article/details/48679231 本文出自:【陈传恒的博客】

这些天遇到一个很奇怪的问题,很奇怪的问题,很奇怪的问题。重要的事情要说三遍。奇怪的问题大都是在解决之间很奇怪,如果你解决之后你会发现奇怪的是你自己。下面我来说一下我是怎么奇怪了一把的。

这个奇怪的问题(其实不奇怪)是跟ListView有关系。先说问题和解决办法:java.lang.Class Cast Exception: android.widget.HeaderViewListAdapter这么一个异常。那么你就要看看你的listView.addFooterView是不是放在了listView.setAdaptr后面了。咋办呢,把它放前面就好了。

下面来说说出问题的愿意,这里有一个HeaderViewListAdapter,首先你回想:这是什么鬼。没见过这个类,哪里来的转换异常。下面咱们看一下源码:

    @Override
    public void setAdapter(ListAdapter adapter) {
        

        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }
    
    }
这段代码是listView中的源码,源代码有很多行,不过咱们不用看,就这一段就可以。有木有发现HeaderViewListAdapter这个鬼。这里的if判断中的mHeaderViewInfos和mFooterViewInfos就是咱们加的listView的header和footer。至于.size()这个方法,咱们暂且理解为你是否为listView add过header或者footer。稍后再来详细说明一下。想必大家能够理解了,如果你设置了header或者footer中的其中一个,就会New出一个HeaderViewListAdapter,然后传入三个参数分别是header和footer和你传入的adapter。没设置的话就直接是你创建的那个adapter了。 下面看这段源代码:

    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;
    }
看到没有。listView调用的的时候是 HeaderViewListAdapter来执行的,由于你没有先设置header或者footer,导致adapter还是原来的,并不是HeaderViewListAdapter。结果就会出现咱们遇到的类转换异常了。

-------------------这里是分割线,下面的已经和问题无关,这里只做拓展----------------------


下面再来说一下上面提到的mHeaderViewInfos.size()和mFooterViewInfos.size()。这里只是来说明为什么是.size(),而不是用是否为null来判断,咱们还是来看源码:

/**
     * A class that represents a fixed view in a list, for example a header at the top
     * or a footer at the bottom.
     */
    public class FixedViewInfo {
        /** The view to add to the list */
        public View view;
        /** The data backing the view. This is returned from {@link ListAdapter#getItem(int)}. */
        public Object data;
        /** <code>true</code> if the fixed view should be selectable in the list */
        public boolean isSelectable;
    }
    private ArrayList<FixedViewInfo> mHeaderViewInfos = Lists.newArrayList();
    private ArrayList<FixedViewInfo> mFooterViewInfos = Lists.newArrayList();

看到了吧,这里是new出来的,咋能用null判断呢。

再来往下看addHeaderView和addFooterView之后,会走源码中的下面这两个方法:

    public void addHeaderView(View v) {
        addHeaderView(v, null, true);
    }
    public void addFooterView(View v) {
        addFooterView(v, null, true);
    }
大家能看到这两个方法什么事都没干,只是调用了相同方法名的方法,并且传入了三个参数,其实这两个方法我们也是可以直接调用的,只是不掉用也是没有任何问题的。下面咱们来说说这三个参数是做什么的。还是看源码:!- -!

    public void addHeaderView(View v, Object data, boolean isSelectable) {
        final FixedViewInfo info = new FixedViewInfo();
        info.view = v;
        info.data = data;
        info.isSelectable = isSelectable;
        mHeaderViewInfos.add(info);
        // 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 header view, or adding one later on,
            // we need to notify the observer.
            if (mDataSetObserver != null) {
                mDataSetObserver.onChanged();
            }
        }
    }
由于addFooterView和addHeaderView非常类似,这里我就补贴代码了。咱们主要来说明这三个参数是什么。

第一个参数:View v,我就不多说了,就是咱们传进来的View。

第二个参数:Object data,这个就是你header中的数据,你传入之后在点击header的时候可以用getItem(int)这个方法获取出来。当然也是可以不传的,咱们是可以通过别的方法做出和点击同样效果的,我就不说了,大家都懂得。

第三个参数:boolean isSelectabe,简单来说,就是为了让header或者footer可不可点的,true就是能点击,索引就是0。false就是不能点击了

------------------这里是分割线,拓展结束------------------

好了就这么多。希望对大家有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值