listview
2015-07-06 14:51
316 查看
getChildAt
Listview可以有header有footer,在普通listview的上下方,随着滚动会出现或者消失Listview的mChildren是可见部分的item(可以是header,footer)的集合,所以ListView.getChildAt(int position),
这个position指的是在可视的item中的索引,跟cursor里的位置是大不一样的。可以看看ListView.getChildCount()函数得到个数是小于或等于Cursor里的个数的(不考虑header的话)。虽然一共可能有20条数据,但是界面只能看到8条,那么这个ChildCount大约就是8了。
getTop
View firstChild =view.getChildAt(0);int top = firstChild.getTop();
这段代码是获取第一个可见项与listview本身的高度距离,如图,测试数据1有部分在屏幕外,有部分在屏幕内,假设在屏幕外部分为20px,屏幕内部分为30px,那他的top值就是-20px
listview滚动距离
我们怎么知道一个listview滚动了多少呢,可能会先想到视图的基类方法getScrollY(),但此方法给ScrollView使用没有问题,因为ScrollView没有复用机制。ListView的父容器里永远只有可见的item,整个容器其实并没有相对屏幕移动,因此getScrollY()总是为0。有方法如下:
public int getScrollY() {
View c = mListView.getChildAt(0);
if (c == null) {
return 0;
}
int firstVisiblePosition = mListView.getFirstVisiblePosition();
int top = c.getTop();
return -top + firstVisiblePosition * c.getHeight() ;
}
这个方法只适用于所有的item一样高的
分割线问题
使用listview自带的分割线经常出现奇怪的问题,比如顶部多了跟线(比如item数量为0,只有head),比如底部少了跟线,可以看下面的文章http://blog.csdn.net/xiaoxiaobian3310903/article/details/7182231
http://www.cnblogs.com/mengshu-lbq/archive/2012/04/07/2435883.html http://gundumw100.iteye.com/blog/1169065
我觉得还是不要用他的线好了,自己在viewholder里面画跟线得了
改变数据size的操作必须在主线程
listview对应的数据arraylist,会由一些操作,比如add,remove,这些操作会改变数组的size,尽量把这些操作和notifyDataSetChanged一起放到ui线程中去,如果数据操作在非ui线程内,可能会导致崩溃,日志如下E/AndroidRuntime(16779):java.lang.IllegalStateException: The content of the adapter has changed butListView did not receive a notification. Make sure the content of your adapteris not modified from a background thread, but only from the UI thread. Makesure
your adapter calls notifyDataSetChanged() when its content changes.
这个崩溃是listview的layoutChildren触发的,代码如下
[java] view
plaincopy
if (mItemCount == 0) {
resetList();
invokeOnItemScrollListener();
return;
} else if (mItemCount != mAdapter.getCount()) {
throw newIllegalStateException("The content of the adapter has changed but "
+ "ListView didnot receive a notification. Make sure the content of "
+ "your adapter isnot modified from a background thread, but only from "
+ "the UI thread.Make sure your adapter calls notifyDataSetChanged() "
+ "when itscontent changes. [in ListView(" + getId() + ", " + getClass()
+ ") withAdapter(" + mAdapter.getClass() + ")]");
}
listview会在layoutChildren内部去检查mItemCount !=mAdapter.getCount()。
如果我们在子线程改变数据,在主线程内更新notifyDataSetChanged,这2个之间有时间差,如果在这2个操作之间 listview执行onLayout,就会调用layoutChildren,此时mAdapter.getCount()已经改变,但是还没有notifyDataSetChanged,所以mItemCount没有变化,导致崩溃
可参考http://www.cnblogs.com/monodin/p/3874147.html
参考资料
http://blog.csdn.net/lilybaobei/article/details/8142987相关文章推荐
- 求出目录的大小
- Android App集成支付宝
- 城市的三级联动
- 查看IIS上面的每个网站分别用了多少内存
- C++ Bit Fields
- javascript
- jQuery的笔记
- 3月3号 阶段性考试 IO
- 面试常考题---交换变量
- C3第 1 节: 泛型集合及练习
- C2第 1 节值类型引用类型介绍和字符串练习
- C1第 1 节: 面向对象类的介绍和继承
- B7第七章第 1 节: ADO.Net简介
- B6第六章 第 6 节: MYSQL常用数据类型
- B5第五章第1节String常用方法1
- vs使用指南
- A2第8节枚举类型
- A4第四章第2节null和成员变量、局部变量的不同初始化
- A3第三章第1节For循环入门
- C#后台拼接jquery 中的超链接并绑定事件