ListView调用notifyDataSetChanged(),listview显示跳到最后的item上
**.listview的adapter的绑定侦听事件,(比如OnclickListener事件),不能写在
1
2
3
4
5
6
7
8
9
|
if (convertView == null ) { convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag(); } |
这个代码块中,因为自定义的onclick事件一般要封装一个int position的代表当前点击的listview的item在data中的位置,但是由于使用了viewHolder优化,position的位置,并不是setTag()中的position的位置,(这个没有具体搞清楚原因),所以如果把setOnClickListener()写在setTag()的代码块中,当数据源变化,特别是数据源是LinkedList的格式,头部增加数据时,position就不是原来封装的位置,这个时候就会发生点击错误。
所以,绑定侦听事件的代码应该写在设置数据源的代码块中,(以上代码的else之后)
**.listview的android:transcriptMode="alwaysScroll" 属性是控制:当数据源有变化时,或者显式调用notifyDataSetChanged时,listview自动跳转到最后一条的功能。
根据实际需求选择这个属性。
**.ListView不通过notifyDataSetChanged()更新指定的Item
Listview一般大都是通过notifyDataSetChanged()來更新listview,但通过notifyDataSetChanged()会把界面上现实的的item都重绘一次,这样会影响ui性能。
可以通过更新指定的Item提高效率,伪代码如下:
1
2
3
4
5
6
7
8
9
10
11
|
private void updateView( int itemIndex){ int visiblePosition = yourListView.getFirstVisiblePosition(); View v = yourListView.getChildAt(itemIndex - visiblePosition); //Do something fancy with your listitem view TextView tv = (TextView)v.findViewById(R.id.sometextview); tv.setText( "Hi! I updated you manually" ); } |
下面这段话很有启发,特别是对listview滑动后item混乱的情况(包括异步加载图片,图片变小的问题)
ListView的Tag用法也不算很错,而是用的时候没有注意设置的时候要注意“对称”。
Tag本身可以理解成放ViewHolder,那么和ViewHolder的加速只不过是存放的位置不同,加速效果基本一致。
“对称”我所指的内容是:
不管你要显示的数据的逻辑是如何的,如果你设置了某个View的宽度,那么在任何一种数据的填充UI逻辑里面,不可以有不设置这个View宽度的代码路径。
简单的例子就是,我根据某个布尔值,如果是false的话,将ImageView设置为View.INVISIBLE
if ( item.isHidden()){
mImage.setVisibility(View.INVISIBLE);}
这样是错误的,因为如果这里缓存的UI控件的状态会被复用到其它item上,而这个item恰巧可能是需要显示的。
必须补上else语句
else{
mImage.setVisibility(View.VISIBLE);}
这个估计就是那位仁兄拖动图片变小的原因了。
最后说一下,ListView控件条目部分,一共产生的条目是屏幕能容纳的数目+2(还是+1?我记不清楚了),然后循环使用。