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

  1. ListView listView = new ListView(this);
  2. listView.addFooterView(mItem);
  3. listview.setAdapter(mAdapter);
  4. listview.getAdapter();

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

我们看一下addFooterView方法

  1. public void addFooterView(View v, Object data, boolean isSelectable) {
  2. final FixedViewInfo info = new FixedViewInfo();
  3. info.view = v;
  4. info.data = data;
  5. info.isSelectable = isSelectable;
  6. mFooterViewInfos.add(info);
  7. mAreAllItemsSelectable &= isSelectable;
  8.  
  9. // Wrap the adapter if it wasn't already wrapped.
  10. if (mAdapter != null) {
  11. if (!(mAdapter instanceof HeaderViewListAdapter)) {
  12. mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
  13. }
  14.  
  15. // In the case of re-adding a footer view, or adding one later on,
  16. // we need to notify the observer.
  17. if (mDataSetObserver != null) {
  18. mDataSetObserver.onChanged();
  19. }
  20. }
  21. }

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

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

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

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

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

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

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

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

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

getcount方法

  1. public int getCount() {
  2. if (mAdapter != null) {
  3. return getFootersCount() + getHeadersCount() + mAdapter.getCount();
  4. } else {
  5. return getFootersCount() + getHeadersCount();
  6. }
  7. }

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

  1.                    Adapter a = listView.getAdapter();
  2. ConversationListAdapter adapter = null;
  3. if (a instanceof HeaderViewListAdapter) {
  4. adapter = (ConversationListAdapter) ((HeaderViewListAdapter) a).getWrappedAdapter();
  5. } else if (a instanceof ConversationListAdapter) {
  6. adapter = (ConversationListAdapter) a;
  7. } else {
  8. android.util.Log.e("zhangshuli", "a=="+a);
  9. }

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

ListView-添加head跟foot item 问题的更多相关文章

  1. 为ListView添加头和脚

      转自:https://software.intel.com/zh-cn/blogs/2014/12/15/android-listview-addheaderview-addfooterview ...

  2. 自定义listView添加滑动删除功能

    今天研究了一下android里面的手势,结合昨天学习的自定义View,做了一个自定义的listview,继承自listView,添加了条目的滑动手势操作,滑动后出现一个删除按钮,点击删除按钮,触发一个 ...

  3. ListView添加图片文字项

    1)listview 控件 结合 imagelist 控件 实现类似效果. 2)添加 imagelist 控件 images 属性,点击后面的... 添加相应图片. 3)点listview,查看其属性 ...

  4. Android之listview添加数据篇

    一.ListView: 1. ListView通常有两个职责: 1.向布局填充数据 2.处理选择点击等操作 2.ListView的创建需要3个元素: 1. ListView中的每一列的View. 2. ...

  5. 仿喜马拉雅实现ListView添加头布局和脚布局

     ListView添加头布局和脚布局 之前学习喜马拉雅的时候做的一个小Demo,贴出来,供大家学习参考: 如果我们当前的页面有多个接口.多种布局的话,我们一般的选择无非就是1.多布局:2.各种复杂滑动 ...

  6. listview当选中某一个item时设置背景色其他的不变

    listview当选中某一个item时设置背景色其他的不变: 可以使用listview.setOnFoucsChangeListener(listener) ; /** * listview获得焦点和 ...

  7. ListView添加项目带序列

    ListView添加项目带序列     function AddSelItems(listview1:TListView;ListView2:TListView):Boolean;var  s: st ...

  8. Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item

    1. 这里就是实现一个很简单的功能,使用ListView实现左右滑动删除Item: (1)当我们在ListView的某个Item,向左滑动显示一个删除按钮,用户点击按钮,即可以删除该项item,并且有 ...

  9. Android ListView 之 SimpleAdapter 二 (包含 item 中按钮监听)

    1    MainActivity.java package com.myadapter; import java.util.ArrayList; import java.util.HashMap; ...

  10. ListView添加节点

    ListView插入节点的流程 当ListView控件的样式被设置成report时,ListView控件实际上是分为两个部分, 一部分是Column, 这个部分是用来显示ListView的每一列的标题 ...

随机推荐

  1. 131.typename在嵌套类中的作用

    #include <iostream> using namespace std; class myit { public: static int num; class itit { }; ...

  2. TPC-C测试

    TPC发布的测试标准之一,是专门针对联机事务处理系统(OLTP)的测试标准.1992年发布1.0版本.最新版本5.11,2010年发布. 测试规范中模拟了一个比较复杂并具有代表意义的OLTP应用环境, ...

  3. github下载速度慢解决方法

    1.获取 global.ssl.fastly地址 访问 http://github.global.ssl.fastly.net.ipaddress.com/#ipinfo 获取cdn域名以及ip地址  ...

  4. 洛谷 P2147 [SDOI2008]洞穴勘测 LCT

    Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...

  5. git新克隆代码的时候ssh协议

  6. NodeJS学习笔记 (25)逐行读取-readline(ok)

    模块概览 readline是个非常实用的模块.如名字所示,主要用来实现逐行读取,比如读取用户输入,或者读取文件内容.常见使用场景有下面几种,本文会逐一举例说明. 文件逐行读取:比如说进行日志分析. 自 ...

  7. 记intel杯比赛中各种bug与debug【其四】:基于长短时记忆神经网络的中文分词的实现

    (标题长一点就能让外行人感觉到高大上) 直接切入主题好了,这个比赛还必须一个神经网络才可以 所以我们结合主题,打算写一个神经网络的中文分词 这里主要写一下数据的收集和处理,网络的设计,代码的编写和模型 ...

  8. Jupyter Notebook 常用的快捷键

    Jupyter Notebook 有两种键盘输入模式.编辑模式,允许你往单元中键入代码或文本:这时的单元框线是绿色的.命令模式,键盘输入运行程序命令:这时的单元框线是灰色. Shift+Enter : ...

  9. 洛谷——P1019 单词接龙(NOIP2000 T3)

    https://www.luogu.org/problem/show?pid=1019#sub 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...

  10. 九、 HBase SHELL、 JAVA 和 Thrift 客户端

    HBase 由 Java 语言实现,同时他也是最主要最高效的客户端. 相关的类在org.apache.hadoop.hbase.client 包中.涵盖所有 增删改查 API . 主要的类包含: HT ...