- ListView顾名思义,可用于显示view的列表。
ListView的使用:Listview+adapter+数据源
其中适配器是用于将数据源中的数据映射到ListView中,而这种关联的建立通常是在adapter的构造函数中实现。 - 与LIstView相关的适配器一般有4种;
首先是:ArrayAdapter 三个参数,用来显示列表简单内容。
1,布局通常采用系统自带的;
2,数据源可以是普通数组或者List数组(getData()获得);
其次是:SimpleAdapter 五个参数,通常不需要自定义实体类,但是需要自己手动写item项的布局效果。(eg:一个典型的列子)
SimpleAdapter adapter=
new SimpleAdapter(this, getPersons(), R.layout.personitem,
new String[]{"name","age","school"},new int[]{R.id.id_name,R.id.id_age,R.id.id_school});
private List<Map<String, Object>> getPersons(){
List<Map<String, Object>> persons=new ArrayList<Map<String,Object>>();
for (int i=0; i<10; i++){
Map<String, Object> map=new HashMap<String, Object>();
map.put("name", "name_"+i);
map.put("age", 10+i);
map.put("school", "schoool_"+i);
persons.add(map);
}
return persons;
}
最后是:BaseAdapter,这也是实际开发过程中和listview搭配使用最多的适配器,步凑:
- 创建listview每行显示的布局文件;
- 创建数据源实体对象ItemBean类,用来封装listview中每行显示的数据内容。
-
自定义适配器类extends自BaseAdapter,重写其中的必要的方法。
最后是CursorAdapter,一般用于显示数据库数据。- ListView的常见优化之ViewHolder
所谓的优化一般是指对重写方法getView()的改进,首先来看不使用优化的方式重写getView():
- ListView的常见优化之ViewHolder
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
View view=inflater.inflate(R.layout.item, null);
ImageView imageView=(ImageView) view.findViewById(R.id.imageview);
TextView title=(TextView) view.findViewById(R.id.title);
TextView content=(TextView) view.findViewById(R.id.content);
imageView.setImageResource(mlist.get(arg0).getImg_id());
title.setText(mlist.get(arg0).getTitle());
content.setText(mlist.get(arg0).getContent());
return view;
}
注释:其中getview()方法在listview每次要加载一个新的item时候的时候调用,即是说
ListView针对List中每个item,要求adapter给我一个视图(getView())。
而其中findviewById()是比较耗时的操作,且并没有使用到ListView的缓存机制。
要知道在提供ListView的同时Android中还有个有个叫做Recycler的View缓冲池,它的目的就在于缓存那些刚刚还用于显示,但是目前却因为滑动而不再显示的item。同时系统将每个Recyler中的item以参数的形式传入了getView()方法中,即View convertView,所有就可以利用它来减少创建view的过程。
即是说:我们可以将上面的View view=inflater.inflate(R.layout.item, null);该成
if(convetView==null){
convetView=inflater.inflate(R.layout.item, null);
}
就避免了重复的创建view;
- 上面说过findviewbyId()是比较耗时的操作,于是下面就采用ViewHandler来进行优化。使用Viewholder充分利用了LIstView的缓存机制,避免了每次调用GetView的时候都通过findViewById()来实列化控件。
具体的代码:
@Override
public View getView(int position, View convetView, ViewGroup arg2) {
ViewHodler hodler;
if(convetView==null){ //使用viewholder简化每次findviewbyid的操作
hodler=new ViewHodler();
convetView=inflater.inflate(R.layout.item, null);
hodler.iamge=(ImageView) convetView.findViewById(R.id.imageview);
hodler.title=(TextView) convetView.findViewById(R.id.title);
hodler.content=(TextView) convetView.findViewById(R.id.content);
convetView.setTag(hodler); //将试图convertview与holder绑定到一起
}else{
hodler=(ViewHodler) convetView.getTag();
}
ItemBean bean=mlist.get(position);
hodler.iamge.setImageResource(bean.getImg_id());
hodler.title.setText(bean.getTitle());
hodler.content.setText(bean.getContent());
return convetView;
}
class ViewHodler{
public ImageView iamge;
public TextView title;
public TextView content;
}
}
解释:此Item用于显示一张图,两个文本。
附:android:divider="#0000" //去掉listview分割线
- 用ListView实现聊天界面效果
为适配器重写两个方法:
@Override
public int getItemViewType(int position) {
return mlist.get(position).getType_id();//ItemBean中封装了聊天内容的类型
}
@Override
public int getViewTypeCount() {
return 2;
}
在getView()方法中增加一个判断
if(getItemViewType(position)==0){
//加载左边的布局
}else if(getItemViewType(position)==1){
// 加载右边的布局
}
6.为Listview添加点击事件
listview的点击事件常用的有两种,一种是单项点击事件,一种是长按事件。
mListview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int postion, long arg3) {
Log.i("info", "onItemClick postion="+postion+"arg3="+arg3);
}
});
mListview.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int postion, long arg3) {
// TODO Auto-generated method stub
Log.i("info", "onItemLongClick postion="+postion+"arg3="+arg3);
return false;
}
});
注:
其中两个方法中的第三个参数postion,指向了被点击的坐标,坐标从0 开始。
7.Listview删除Item
Listview中删除item的方式常用的有两种,一种是通过侧滑的方式实现,一种是在长按事件中通过contextmenu来实现。
具体的办法是:1,删除对应项的数据 2,调用 adapter.notifyDataSetChanged();来通知适配器数据源发生了变化,从而刷新视图。
热门评论
对于ArrayAdapter也可以实现复杂视图的显示,通过继承ArrayAdapter然后重写getView()方法实现。