android ListView 分析(一)
/**
* Gets the data associated with the specified position in the list.
*
* @param position Which data to get
* @return The data associated with the specified position in the list
*/
public Object getItemAtPosition(int position) {
T adapter = getAdapter();
return (adapter == null || position < 0) ? null : adapter.getItem(position);
} public long getItemIdAtPosition(int position) {
T adapter = getAdapter();
return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position);
}
public Object getItem(int position) {
// Header (negative positions will throw an ArrayIndexOutOfBoundsException)
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 ArrayIndexOutOfBoundsException)
return mFooterViewInfos.get(adjPosition - adapterCount).data;
}
这个算是简单的View的包装器
/**
* 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;
}
/**
* Sets the data behind this ListView.
*
* The adapter passed to this method may be wrapped by a {@link WrapperListAdapter},
* depending on the ListView features currently in use. For instance, adding
* headers and/or footers will cause the adapter to be wrapped.
*
* @param adapter The ListAdapter which is responsible for maintaining the
* data backing this list and for producing a view to represent an
* item in that data set.
*
* @see #getAdapter()
*/
@Override
public void setAdapter(ListAdapter adapter) {
if (null != mAdapter) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
} resetList();
mRecycler.clear();
//关键代码 ListView 在 存在headView或者footView的时候,listView设置的adapter并不是我们设置的adapter,而是包装过的HeaderViewListAdapter if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
} ......
}
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int realPosition = position - listView.getHeaderViewsCount();
}
});
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
doSomething(parent.getAdapter().getItem(position));
}
扩展内容,包裹的adapter --> HeaderViewListAdapter ......
import java.util.ArrayList; /**
* 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>();
...... 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();
} ...... 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 Object getItem(int position) {
// Header (negative positions will throw an ArrayIndexOutOfBoundsException)
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 ArrayIndexOutOfBoundsException)
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 View getView(int position, View convertView, ViewGroup parent) {
// Header (negative positions will throw an ArrayIndexOutOfBoundsException)
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 ArrayIndexOutOfBoundsException)
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 Filter getFilter() {
if (mIsFilterable) {
return ((Filterable) mAdapter).getFilter();
}
return null;
}
//获取被包装的adapter,即我们设置的listView
public ListAdapter getWrappedAdapter() {
return mAdapter;
}
}
/**
* List adapter that wraps another list adapter. The wrapped adapter can be retrieved
* by calling {@link #getWrappedAdapter()}.
*
* @see ListView
*/
public interface WrapperListAdapter extends ListAdapter {
/**
* Returns the adapter wrapped by this list adapter.
*
* @return The {@link android.widget.ListAdapter} wrapped by this adapter.
*/
public ListAdapter getWrappedAdapter();
}
安卓源码分析群: Android源码分析QQ1群号:164812238
android ListView 分析(一)的更多相关文章
- android ListView 九大重要属性详细分析、
android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...
- Android ListView异步载入图片乱序问题,原因分析及解决方式
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...
- Android ListView滑动过程中图片显示重复错乱闪烁问题解决
最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决 主要分析Android ListView滚动过程中图片显示重复.错乱.闪烁的原因及解决方法,顺带提及L ...
- [转] Android 性能分析案例
Android 系统的一个工程师(Romain Guy)针对Falcon Pro 应用,撰写了一个Android性能分析的文章.该文章介绍了如何分析一个应用哪里出现了性能瓶颈,导致该应用使用起来不流 ...
- Android 演示 Android ListView 和 github XListView(3-3)
本文内容 环境 项目结构 演示 1:简单 XListView 演示 2:XListView + Fragment 演示 3:XListView + ViewPager + Fragment 本文三个演 ...
- Android 演示 Android ListView 和 github XListView(1-3)
本文内容 环境 项目结构 演示 1:ListView 演示 2:简单 XListView 演示 3:音乐列表 XListView 演示 4:另一个音乐列表 XListView 本文四个演示,循序渐进. ...
- Android ListView工作原理完全解析,带你从源码的角度彻底理解
版权声明:本文出自郭霖的博客,转载必须注明出处. 目录(?)[+] Adapter的作用 RecycleBin机制 第一次Layout 第二次Layout 滑动加载更多数据 转载请注明出处:h ...
- Android ListView工作原理全然解析,带你从源代码的角度彻底理解
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/44996879 在Android全部经常使用的原生控件其中.使用方法最复杂的应该就是 ...
- 老潘 - ListView分析 - 学以致用篇(一)
ListView分析学以致用篇(1) 在我们查看别人的博客的时候,一个人是一个风格的.先说下我的风格,我喜欢思想类比,然后介绍知识,不太喜欢填鸭式的灌输.如果只是想单纯的从我的博客中直接看到代码,我个 ...
随机推荐
- Django模板语言(一)
1,Django模板语言 1.1>基础语法:1.1.1,变量相关:{{ 变量名 }},1.1.2,逻辑相关{% ... %} 在Django模板语言中按此语法使用:{{ 变量名 }},当模板引擎 ...
- Difference between HttpContext.Request and Request
https://stackoverflow.com/questions/5547989/difference-between-httpcontext-request-and-request Well: ...
- mac系统下显示隐藏文件
在终端上输入以下命令即可: 显示隐藏文件命令: defaults write com.apple.finder AppleShowAllFiles -bool true 不显示隐藏文件命令: defa ...
- linux下系统调用劫持ioctl
实验环境:linux 2.6.32 64位系统 采用lkm(动态加载内核模块)方式劫持ioctl系统调用,系统调用过程如图所示(以open为例子) 实验代码:(头文件有不需要的,但是懒得改了,在系 ...
- PHP中的连贯操作
连贯操作有什么好处?就是多行操作可以在一行之内完成,要进行连贯操作的方法必须返回$this,也就是当前类的对象实例,然后就可以进行连贯操作了,具体的实现代码如下所示. <?php /** * p ...
- bzoj 1610: [Usaco2008 Feb]Line连线游戏【瞎搞】
阴沟翻船.jpg 居然忘了除0的情况 枚举两两之间的线,把斜率装起来排个序去个重就好了 真是水的一晚上呢 #include<iostream> #include<cstdio> ...
- bzoj 4069: [Apio2015]巴厘岛的雕塑【dp】
居然要对不同的数据写不同的dp= = 首先记得开long long,<<的时候要写成1ll<<bt 根据or的性质,总体思路是从大到小枚举答案的每一位,看是否能为0. 首先对于 ...
- 5位ID生成方案
最近在某微信技术群,有人问到如何生成5位唯一数字+字母字符串的算法,要保证生成的字符串唯一,且字符串内部也要唯一. 怎么样,这个需求是不是很简单,也有点特殊呢?简单是指需求简单,特殊是指,字符串长度要 ...
- 线程池之ThreadPoolExecutor使用
ThreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线 ...
- sublime 解决中文乱码
步骤: 在Sublime Text里,按ctrl+`,打开Console,一次性输入如下代码: import urllib.request,os; pf = 'Package Control.subl ...