1.ListView常用优化
重用convertView, 使用viewHolder setTag(),getTag()减少使用findViewByID
@Override public View getView(int i, View convertView, ViewGroup viewGroup) { ViewHolder holder = null; //判断是否缓存 if(convertView == null){ holder = new ViewHolder(); //实例化布局 LayoutInflater mInflater = LayoutInflater.from(lvActivity.this); convertView = mInflater.inflate(R.layout.lv_item_layout,null); holder.tv = (TextView)convertView.findViewById(R.id.textView); holder.iv = (ImageView)convertView.findViewById(R.id.imageView); convertView.setTag(holder); } else{ holder = (ViewHolder)convertView.getTag(); } holder.iv.setBackgroundResource(R.drawable.a); holder.tv.setText(getItem(i).toString()); return convertView; } public final class ViewHolder{ public TextView tv; public ImageView iv; }
2.ListView的一些常用效果 (xml里面的listview标签下)
//无分隔线
android:divider="@null"
//灰色分隔线
android:divider="@android:color/darker_gray"
android:dividerHeight="10dp"
//没有滚动条
android:scrollbars="none"
//没有点击效果(系统默认会变成淡灰,这里也可以设成图片)
android:listSelector="#00000000"
//添加刷新后,自动跳到刚才添加的那条
data.add(data.size(),"我是新来的");
adapter.notifyDataSetChanged();
lv.setSelection(N);
3.获取可见的某个item进行修改
int num = lv.getChildCount(); //获取可见的条目总数
View view1 = lv.getChildAt(3); //获取可见的第N个条目,注意:这个值不能大于num-1。 多了就会空指针
((TextView) view1.findViewById(R.id.textView)).setText("我被修改了"); //修改内容
4.滑动监听
lv.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: Toast.makeText(lvActivity.this,"触摸屏幕",Toast.LENGTH_SHORT).show(); break; case MotionEvent.ACTION_MOVE: Toast.makeText(lvActivity.this,"滑动",Toast.LENGTH_SHORT).show(); break; case MotionEvent.ACTION_UP: Toast.makeText(lvActivity.this,"离开屏幕",Toast.LENGTH_SHORT).show(); break; } return false; } }); lv.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int state) { switch (state) { case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: Toast.makeText(lvActivity.this,"离开屏幕1",Toast.LENGTH_SHORT).show(); break; case AbsListView.OnScrollListener.SCROLL_STATE_FLING: Toast.makeText(lvActivity.this,"惯性滚动",Toast.LENGTH_SHORT).show(); break; case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: Toast.makeText(lvActivity.this,"触摸屏幕1",Toast.LENGTH_SHORT).show(); break; } } @Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //滚动时一直回调 //firstVisibleItem 当前可见的第一个Item的ID //visibleItemCount 当前可见的item 总数(显示一小半也算) //totalItemCount 整个listView的item 总数 } });
5.聊天ListView 及多种布局的ListView
a.准备好不同的布局文件
b.在适配器里多重写两个方法(这里只有2种type,随便写了下)
@Override public int getItemViewType(int position) { if(position%2 == 0){ return 1; } return 0; } @Override public int getViewTypeCount() { return 2; }c.在getView()里面根据不同的type加载不同的布局,再设置内容就可以了
@Override public View getView(int i, View convertView, ViewGroup viewGroup) { ViewHolder holder = null; //判断是否缓存 if(convertView == null){ holder = new ViewHolder(); //根据不同的type加载布局 LayoutInflater mInflater = LayoutInflater.from(chatActivity.this); if(getItemViewType(i)==1){ convertView = mInflater.inflate(R.layout.chat_me, null); } else { convertView = mInflater.inflate(R.layout.chat_you, null); } holder.tv = (TextView)convertView.findViewById(R.id.textView); convertView.setTag(holder); } else{ holder = (ViewHolder)convertView.getTag(); } holder.tv.setText(getItem(i).toString()); return convertView; } public final class ViewHolder{ public TextView tv; }
6.关于ListView里面数据混乱
网上有大量的经验,这里只做个人总结。
1.出现数据混乱的主要原因是在getView的时候重用了 convertView 和 viewHolder。
2.getView() 的时候会根据 item 数量的多少,重复的构造每一个item.
3.当我们滑动时,有的item消失,有的item出现。为了节省资源,系统会把消失的item当做容器,放入新item的内容展示出来。
4.在这个时候,我们会设置一些新的值。 而如果我们没有设置新的值,就会默认使用缓存里面的值。 所以就会数据混乱。
5.所以在使用listView的时候,最好保证convertview里的每一个内容都给了新的值,如果为空可以给个空值,这样不会出现混乱