ListView的HeaderView

标签:Androidlistviewpositionhearderview 11599人阅读 评论(0) 收藏 举报 分类: android(176)

目录(?)[+]


今天突然发现ListView的OnItemClickListener监听事件中的position返回是从1开始的,一直觉得很奇怪,在群里问了后,可能是headerView的问题,特意去查了一番,原来是如此:

特此记过!

(1)添加HeaderView之后尺寸布局被忽略。

通常添加头部的方法是
?
1 2 3 LayoutInflater lif = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View headerView = lif.inflate(R.layout.header, null ); mListView.addHeaderView(headerView);

原因:
lif.inflate(R.layout.header, null)丢失了XML布局中根View的LayoutParam,应该使用的是
?
1 lif.inflate(R.layout.header, mListView, false );

(2)添加HeaderView之后导致OnItemClickListener的position移位

OnItemClickListener接口的方法:
?
1 void onItemClick(AdapterView<?> parent, View view, int position, long id)

position通常是从0开始的,但是添加了HeaderView之后,position也会将HeaderView的数目计算进去。
几个解决办法:
1,手动计算真实的position位置:
?
1 2 3 4 5 6 7 8 final headerCount = 1 ; mListView.setOnItemClickListener( new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Item item = myAdapter.getItem(position - headerCount); } });

2,其实上面的步骤ListView已经为我们提供了,所以可以改写为:
?
1 2 3 4 5 6 7 mListView.setOnItemClickListener( new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Item item = parent.getAdapter().getItem(position); } });
原因在源码中有比较清晰的解释:
当有headerView被添加时,实际传递给ListView的adapter被包装,parent.getAdapter()返回真实被ListView使用的Adapter(HeaderViewListAdapter),HeaderViewListAdapter的getItem(int)方法处理了position的问题。

(3)LayoutInflater的infalte()

用来呼应第一个问题。LayoutInflater的作用很简单,就是将XML的布局文件“翻译”成相应的View对象,而且出于性能的考虑,LayoutInflater只能处理编译后的XML文件,而不能处理通常明文编码的XML文件。
最常用的一个方法:
?
1 View inflate( int resource, ViewGroup root, boolean attachToRoot)

其中:
resource 是布局文件ID
root 是父ViewGroup对象,
attachToRoot 是是否将“翻译”出来的View添加到上面的root中

root和attachToRoot是共同作用的:
1,有root,同时attachToRoot为false,那么inflate()返回的就是“翻译”得到的view
2,有root,同时attachToRoot为true,那么inflate()就是将“翻译”得到的view添加到root后,然后返回root
3,无root,同时attachToRoot为false,那么inflate()返回的就是“翻译”得到的view。
4,无root,同时attachToRoot为true,报错。

另外,root还有一个重要的作用就是为“翻译”得到的view添加合适的LayoutParam,并且如果并不想将得到的View添加到root的话,传递何种root是并没有要求的,比如:
?
1 2 3 View view = mLayoutInflater.inflate(R.layout.header, new ListView(mContext), false ); View view = mLayoutInflater.inflate(R.layout.header, new LinearLayout(mContext), false ); View view = mLayoutInflater.inflate(R.layout.header, new RelativeLayout(mContext), false );
上面得到的View,除了view的LayoutParam分别为AbsListView.LayoutParams,LinearLayout.LayoutParams,RelativeLayout.LayoutParams之外,内容都一致。


转载地址: http://my.oschina.net/xesam/blog/155542#OSC_h2_1

更多相关文章

  1. Android(安卓)Studio(2.3.3)配置Kotlin笔记
  2. android有用代码片段(一)
  3. Android(安卓)OpenCV使用1_导入OpenCV并依赖该项目
  4. android 添加自定义theme和style
  5. Android(安卓)个性化控件整理
  6. Cocos2d-x 3.2导入到Eclipse后出现The import org.cocos2dx.lib
  7. android 添加核心层服务
  8. Android添加权限AndroidManifes.xml
  9. android webview的 一些设置(js java交互)

随机推荐

  1. Flutter在Android(安卓)Studio上的初启动
  2. android如何在子线程中更新UI
  3. make: *** [out/host/linux-x86/obj/EXEC
  4. [Android]判断一个app运行在foreground
  5. 【Android】使RecyclerView 支持setEmpty
  6. Android EditText获取焦点事件
  7. Android jar包Proguard混淆方法
  8. Android 自制照相机
  9. Android中SQLite增删改查的方法(Android开
  10. Android(安卓)使用GPS定位获取经纬度的方