该类其实就是普通使用的Adapter的一个包装类,就是为了添加header和footer而定义的。
该类一般不直接使用,当ListView有header和footer时,ListView中会自动把Adapter封装成一个HeaderViewListAdapter。
源码很简单,相信都能看懂的。下面是android-23版本的源码 /**
* ListAdapter used when a ListView has header views. This ListAdapter
* wraps another one and also keeps track of the header views and their
* associated data objects.
*<p>This is intended as a base class; you will probably not need to
* use this class directly in your own code.
*/
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; // Used as a placeholder in case the provided info views are indeed null.
// Currently only used by some CTS tests, which may be removed.
static final ArrayList<ListView.FixedViewInfo> EMPTY_INFO_LIST =
new ArrayList<ListView.FixedViewInfo>(); boolean mAreAllFixedViewsSelectable; private final boolean mIsFilterable; public HeaderViewListAdapter(ArrayList<ListView.FixedViewInfo> headerViewInfos,
ArrayList<ListView.FixedViewInfo> footerViewInfos,
ListAdapter adapter) {
mAdapter = adapter;
mIsFilterable = adapter instanceof Filterable; if (headerViewInfos == null) {
mHeaderViewInfos = EMPTY_INFO_LIST;
} else {
mHeaderViewInfos = headerViewInfos;
} if (footerViewInfos == null) {
mFooterViewInfos = EMPTY_INFO_LIST;
} else {
mFooterViewInfos = footerViewInfos;
} mAreAllFixedViewsSelectable =
areAllListInfosSelectable(mHeaderViewInfos)
&& areAllListInfosSelectable(mFooterViewInfos);
} public int getHeadersCount() {
return mHeaderViewInfos.size();
} public int getFootersCount() {
return mFooterViewInfos.size();
} public boolean isEmpty() {
return mAdapter == null || mAdapter.isEmpty();
} private boolean areAllListInfosSelectable(ArrayList<ListView.FixedViewInfo> infos) {
if (infos != null) {
for (ListView.FixedViewInfo info : infos) {
if (!info.isSelectable) {
return false;
}
}
}
return true;
} public boolean removeHeader(View v) {
for (int i = 0; i < mHeaderViewInfos.size(); i++) {
ListView.FixedViewInfo info = mHeaderViewInfos.get(i);
if (info.view == v) {
mHeaderViewInfos.remove(i); mAreAllFixedViewsSelectable =
areAllListInfosSelectable(mHeaderViewInfos)
&& areAllListInfosSelectable(mFooterViewInfos); return true;
}
} return false;
} public boolean removeFooter(View v) {
for (int i = 0; i < mFooterViewInfos.size(); i++) {
ListView.FixedViewInfo info = mFooterViewInfos.get(i);
if (info.view == v) {
mFooterViewInfos.remove(i); mAreAllFixedViewsSelectable =
areAllListInfosSelectable(mHeaderViewInfos)
&& areAllListInfosSelectable(mFooterViewInfos); return true;
}
} return false;
} public int getCount() {
if (mAdapter != null) {
return getFootersCount() + getHeadersCount() + mAdapter.getCount();
} else {
return getFootersCount() + getHeadersCount();
}
} public boolean areAllItemsEnabled() {
if (mAdapter != null) {
return mAreAllFixedViewsSelectable && mAdapter.areAllItemsEnabled();
} else {
return true;
}
} public boolean isEnabled(int position) {
// Header (negative positions will throw an IndexOutOfBoundsException)
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return mHeaderViewInfos.get(position).isSelectable;
} // Adapter
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getCount();
if (adjPosition < adapterCount) {
return mAdapter.isEnabled(adjPosition);
}
} // Footer (off-limits positions will throw an IndexOutOfBoundsException)
return mFooterViewInfos.get(adjPosition - adapterCount).isSelectable;
} public Object getItem(int position) {
// Header (negative positions will throw an IndexOutOfBoundsException)
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return mHeaderViewInfos.get(position).data;
} // Adapter
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getCount();
if (adjPosition < adapterCount) {
return mAdapter.getItem(adjPosition);
}
} // Footer (off-limits positions will throw an IndexOutOfBoundsException)
return mFooterViewInfos.get(adjPosition - adapterCount).data;
} public long getItemId(int position) {
int numHeaders = getHeadersCount();
if (mAdapter != null && position >= numHeaders) {
int adjPosition = position - numHeaders;
int adapterCount = mAdapter.getCount();
if (adjPosition < adapterCount) {
return mAdapter.getItemId(adjPosition);
}
}
return -1;
} public boolean hasStableIds() {
if (mAdapter != null) {
return mAdapter.hasStableIds();
}
return false;
} public View getView(int position, View convertView, ViewGroup parent) {
// Header (negative positions will throw an IndexOutOfBoundsException)
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return mHeaderViewInfos.get(position).view;
} // Adapter
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getCount();
if (adjPosition < adapterCount) {
return mAdapter.getView(adjPosition, convertView, parent);
}
} // Footer (off-limits positions will throw an IndexOutOfBoundsException)
return mFooterViewInfos.get(adjPosition - adapterCount).view;
} public int getItemViewType(int position) {
int numHeaders = getHeadersCount();
if (mAdapter != null && position >= numHeaders) {
int adjPosition = position - numHeaders;
int adapterCount = mAdapter.getCount();
if (adjPosition < adapterCount) {
return mAdapter.getItemViewType(adjPosition);
}
} return AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
} public int getViewTypeCount() {
if (mAdapter != null) {
return mAdapter.getViewTypeCount();
}
return 1;
} public void registerDataSetObserver(DataSetObserver observer) {
if (mAdapter != null) {
mAdapter.registerDataSetObserver(observer);
}
} public void unregisterDataSetObserver(DataSetObserver observer) {
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(observer);
}
} public Filter getFilter() {
if (mIsFilterable) {
return ((Filterable) mAdapter).getFilter();
}
return null;
} public ListAdapter getWrappedAdapter() {
return mAdapter;
}
}

HeaderViewListAdapter的更多相关文章

  1. HeaderViewListAdapter cannot be cast to listAdapter问题原因及解决办法

    [o] 在listView中添加leaderView 和footerView的时候要注意在setAdapter之前调用,不然会报如下异常: listAdapter cannot be cast to ...

  2. Android源码分析:HeaderViewListAdapter

    http://bj007.blog.51cto.com/1701577/643568 对于手机开发,我一直坚持的是“用iPhone的方式开发iPhone应用,用Android的方式开发Android应 ...

  3. [Exception Android 19] - android.widget.HeaderViewListAdapter.isEnabled

    java.lang.IndexOutOfBoundsException: Invalid index , size at java.util.ArrayList.throwIndexOutOfBoun ...

  4. Xamarin. Android实现下拉刷新功能

    PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...

  5. [Deprecated!] Android开发案例 - 微博正文

    Deprecated! 更好的实现方式: 使用 android.support.design.widget.CoordinatorLayout. 本文详细介绍如何实现如下图中的微博正文页面效果, 其中 ...

  6. java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.

    分析:android 4.2.X及以下的版本,addHeaderView必须在setAdapter之前,否则会抛出IllegalStateException. android 4.2.X(API 17 ...

  7. Android软件开发之ListView 详解【转】

    ListView的使用方法  ListView是Android软件开发中非常重要组件之一,基本上是个软件基本都会使用ListView ,今天我通过一个demo来教大家怎么样使用ListView组件 绘 ...

  8. Android零散

    2016-03-13 Android零散 ListView中嵌套GridView 要实现分组列表这样的效果:点击ListView中的分组名称,即展开此分组显示其包含的项目.使用ExpandableLi ...

  9. PinnedHeaderListView实现删除

    项目中用到四个List集合展示一个页面,并且每个页面都会有一个标题栏.找了半天资料决定用PinnedHeaderListView开源项目.最后需求又来了,需要一个删除的功能,又去网上找资料,发现没有实 ...

随机推荐

  1. 用硬件(Verilog)实现二进制码和格雷码的转换

    格雷码(Gray code)是1880年由法国工程师Jean-Maurice-Emlle Baudot发明的一种编码,是一种绝对编码方式,典型格雷码是一种具有反射特性和循环特性的单步自补码,它的循环. ...

  2. pycharm去掉拼写检查

    http://zhidao.baidu.com/question/523436629.html

  3. plsql使用之debug

    1. 赋予一个普通用户debug权限 2. 收回权限 SQL> grant DEBUG CONNECT SESSION to bmp; Grant succeeded SQL> revok ...

  4. jQuery折叠风琴

    这个效果用jQuery做是很方便的,根本不需要搞得很复杂. 网上有些效果DEMO不仅用了jQuery还引用一两个封装文件,真是匪夷所思. 最初想到了toggle: jQuery(document).r ...

  5. codeforces C. Xor-tree

    http://codeforces.com/problemset/problem/430/C 题意:在一棵上有n个节点,有n-1条边,在每一个节点上有一个值0或1,然后给你一个目标树,让你选择节点,然 ...

  6. c#获取带有汉字的字符串长度

    不知道大家注意没,用c#下自带的str.Length方法获得字符串str长度的时候,返回的总是字符的个数,但是如果字符串中包含汉字的话,一个汉字是占两个字符长度的,获取的长度值就有了问题. 解决方案: ...

  7. Netty4.0学习笔记系列之一:Server与Client的通讯

    http://blog.csdn.net/u013252773/article/details/21046697 本文是学习Netty的第一篇文章,主要对Netty的Server和Client间的通讯 ...

  8. AES加密跨平台出现的问题

    javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.S ...

  9. 转:Mysql读写分离实现的三种方式

    1 程序修改mysql操作类可以参考PHP实现的Mysql读写分离,阿权开始的本项目,以php程序解决此需求.优点:直接和数据库通信,简单快捷的读写分离和随机的方式实现的负载均衡,权限独立分配缺点:自 ...

  10. 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O

    五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O 五种I/O 模式:[1]        阻塞 I/O          ...