从源码看ListView有HeaderView时onItemClick里的position错位的问题
来源:互联网 发布:宁波百度推广公司php 编辑:程序博客网 时间:2024/05/29 04:16
listView = (ListView) findViewById(R.id.test_lv); headerView = LayoutInflater.from(this).inflate(R.layout.activity_position_test_headerview, null); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, datas); listView.addHeaderView(headerView); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Toast.makeText(ListViewPositionTestActivity.this, "Position is : " + i, Toast.LENGTH_SHORT).show(); } });
如上述代码,给listView添加了一个headerView,运行出来之后的position如下图所示:
会发现数据的第一项position变成了1.
我们再来看一段代码:
listView = (ListView) findViewById(R.id.test_lv); headerView = LayoutInflater.from(this).inflate(R.layout.activity_position_test_headerview, null); headerView1 = LayoutInflater.from(this).inflate(R.layout.activity_position_test_headerview, null); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, datas); listView.addHeaderView(headerView); listView.addHeaderView(headerView1); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Toast.makeText(ListViewPositionTestActivity.this, "Position is : " + i, Toast.LENGTH_SHORT).show(); } });
会发现此时数据的第一项position变成了2.(由此也可以总结出,ListView是可以添加多个HeaderView的)
接下来我们分析分析,来看看addHeaderView(View view)的源码:
/** * Add a fixed view to appear at the top of the list. If this method is * called more than once, the views will appear in the order they were * added. Views added using this call can take focus if they want. * <p> * Note: When first introduced, this method could only be called before * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be * called at any time. If the ListView's adapter does not extend * {@link HeaderViewListAdapter}, it will be wrapped with a supporting * instance of {@link WrapperListAdapter}. * * @param v The view to add. * @param data Data to associate with this view * @param isSelectable whether the item is selectable */ 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); mAreAllItemsSelectable &= isSelectable; // Wrap the adapter if it wasn't already wrapped. if (mAdapter != null) { if (!(mAdapter instanceof HeaderViewListAdapter)) { wrapHeaderListAdapterInternal(); } // 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(); } } }
当mAdapter不为空时,执行wrapHeaderListAdapterInternal()方法,我们来接着看看源码:
/** @hide */ protected HeaderViewListAdapter wrapHeaderListAdapterInternal( ArrayList<ListView.FixedViewInfo> headerViewInfos, ArrayList<ListView.FixedViewInfo> footerViewInfos, ListAdapter adapter) { return new HeaderViewListAdapter(headerViewInfos, footerViewInfos, adapter); } /** @hide */ protected void wrapHeaderListAdapterInternal() { mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, mAdapter); }可以看到,mAdapter变成了HeaderViewListAdapter的对象,那么HeaderViewListAdapter又是什么呢?
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); }上面的HeaderViewListAdapter的构造方法,将headerViewInfos、footerViewInfos和之前的adapter传了进来,接下来我们看看这个类中的getCount()方法:
public int getCount() { if (mAdapter != null) { return getFootersCount() + getHeadersCount() + mAdapter.getCount(); } else { return getFootersCount() + getHeadersCount(); } }
public int getHeadersCount() { return mHeaderViewInfos.size(); } public int getFootersCount() { return mFooterViewInfos.size(); }发现了什么?上面的mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, mAdapter);
方法返回的mAdapter的getCount()是 原先adapter的getCount() 和 HeaderView的总数 、FooterView的总数 之和!
这也就解释了为什么上面的两张图的position错位的原因。同理FooterView也是要占据position的值哦~
这里有几点要注意:
1. addHeaderView(View v, Object data, boolean isSelectable) 中有一个参数isSelectable,当这个值设置为true的时候,该HeaderView不能点击,点击无反应。FooterView同理。
2. 看addHeaderView(View v, Object data, boolean isSelectable)方法的注释,你会发现,在Android4.3(即KITKAT,API 19)之前,addHeaderView方法必须在setAdapter方法之前调用,而在API 19之后,addHeaderView方法可以在任何时间调用。所以在项目中要注意这一点。
阅读全文
0 0
- 从源码看ListView有HeaderView时onItemClick里的position错位的问题
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确。
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确
- 当ListView有Header时,onItemClick里的position不正确的解决方案
- 当ListView有Header或footer时,onItemClick里的position不正确,可以用getAdapter()
- 当ListView有Header或footer时,onItemClick里的position不正确,可以用getAdapter()
- Android_ListView_有Header或Footer时onItemClick里的position的问题
- 嵌入式Linux 使用libmad
- 组合数取模
- 设置select下拉框禁用
- hadoop 搭建
- 有相同资源,不同操作的线程
- 从源码看ListView有HeaderView时onItemClick里的position错位的问题
- POJ2778
- Java 机器学习库Smile实战(二)AdaBoost
- caffe绘制训练过程的loss和accuracy曲线
- 网络编程学习笔记一:Socket编程
- (CSU
- Linux网络编程(二)
- JAVA回调函数
- iterator 倒着输出 vector set