您的位置:首页 > 其它

ListView添加头部之后出现位置获取错乱的问题解决方案

2015-11-13 10:13 281 查看
/**

*Addafixedviewtoappearatthetopofthelist.IfaddHeaderViewis

*calledmorethanonce,theviewswillappearintheordertheywere

*added.Viewsaddedusingthiscallcantakefocusiftheywant.

*<p>

*NOTE:CallthisbeforecallingsetAdapter.ThisissoListViewcanwrap

*thesuppliedcursorwithonethatthatwillalsoaccountforheader

*views.

*

*@paramvTheviewtoadd.

*@paramdataDatatoassociatewiththisview

*@paramisSelectablewhethertheitemisselectable

*/

public
void
addHeaderView(Viewv,Objectdata,

boolean
isSelectable){

if
(mAdapter!=
null
){

throw
new
IllegalStateException(

"Cannotaddheaderviewtolist--setAdapterhasalreadybeencalled."
);

}


FixedViewInfoinfo=
new
FixedViewInfo();

info.view=v;

info.data=data;

info.isSelectable=isSelectable;

mHeaderViewInfos.add(info);

}


/**

*SetsthedatabehindthisListView.

*

*Theadapterpassedtothismethodmaybewrappedbya{@linkWrapperListAdapter},

*dependingontheListViewfeaturescurrentlyinuse.Forinstance,adding

*headersand/orfooterswillcausetheadaptertobewrapped.

*

*@paramadapterTheListAdapterwhichisresponsibleformaintainingthe

*databackingthislistandforproducingaviewtorepresentan

*iteminthatdataset.

*

*@see#getAdapter()

*/

@Override

public
void
setAdapter(ListAdapteradapter){

if
(
null
!=mAdapter){

mAdapter.unregisterDataSetObserver(mDataSetObserver);

}


resetList();

mRecycler.clear();


if
(mHeaderViewInfos.size()>
0
||mFooterViewInfos.size()>
0
){

mAdapter=
new
HeaderViewListAdapter(mHeaderViewInfos,mFooterViewInfos,adapter);

}
else
{

mAdapter=adapter;

}


//其它的一些代码这里省略之...

}

从代码和注释里都可以很清楚的得知,
addHeaderView
一定要在
setAdapter
之前调用,如果不这样做,
addHeaderView
会抛出一个异常。Android为什么要这样?这是因为,在
setAdapter
的时候,会针对我遇到的这种情况(也就是添加Header后
position
不正确的这种情况)做些特殊的处理。
setAdapter
在内部判断了当前ListView是否有Header或者Footer,如果没有,就直接使用参数传进来的adapter;如果有,则用一个decorated的
HeaderViewListAdapter
来替换参数。这个
HeaderViewListAdapter
的使命,就是排除Header和Footer,让
position
(当然也包括getItem,getItemId)等方法的
position
参数)正确返回。
分析到这里,解决方案就出来了:在
onItemClick
不要直接使用我们声明的adapter,而是用ListView里的那个decorated
adapter。获取它的方法就是调用
parent.getAdapter()
。当然,如果ListView没有Header和Footer,直接使用声明的adapter也没有问题,不过为了避免出错,还是统一使用decorated
adapter比较好。
把onItemClick改成下面这样,就可以了

@Override

public
void
onItemClick(AdapterView<?>parent,Viewv,

int
position,
long
id){

//
doSomething(parent.getAdapter().getItem(position));

listOut.get((int)
parent.getAdapter().getItemId(position)//这是正确的Id
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: