BaseAdapter需要重写的方法:
getCount(),getItem(int position),getItemId(int position),getView(int position, View convertView, ViewGroup parent)
listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到 listView的长度,然后根据这个长度,调用getView()逐一绘制每一行。如果你的 getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方 法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几行,covertView是从布局文 件中inflate来的布局。我们用LayoutInflater的方法将定义好的item.xml文件提取成View实例用来显示。然后将xml文件中 的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听 器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要 绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(实际上是一个 ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那再绘制下一行,直到绘完为止。
在
BaseAdapter中若需要动态的修改Item中显示的内容,则组要先修改
getView()中的绘制数据,
在下面例子中是ps,然后再调用Adapter中的
在
notifyDataSetChanged()方法进行重绘即可。
public class MyListViewAdapter extends BaseAdapter {
private Context context;
private LayoutInflater factory;
//该类就是数据类
private List<Person> ps;
public MyListViewAdapter(Context context,List<Person> ps) {
this.context = context;
this.factory = LayoutInflater.from(context);
this.ps = ps;
}
//数据重置
public void resetData(List<Person> ps) {
this.ps = ps;
}
//获取数据
public List<Person> getData() {
return ps;
}
@Override
public int getCount() {
return ps.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
//重要方法
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ListItemViewHolder listItemViewHolder = null;
//convertView为null的时候初始化convertView。
if (convertView == null) {
listItemViewHolder = new ListItemViewHolder();
convertView = factory.inflate(R.layout.listitem_maininfo, null);
listItemViewHolder.title = (TextView)convertView.findViewById(R.id.tv_listitem_name);
listItemViewHolder.detail = (TextView)convertView.findViewById(R.id.tv_listitem_detail);
listItemViewHolder.delet = (Button)convertView.findViewById(R.id.btn_listitem_delet);
//这里很重要,不然无法找回数据
convertView.setTag(listItemViewHolder);
} else {
listItemViewHolder = (ListItemViewHolder)convertView.getTag();
}
//为每个控件初始化信息
listItemViewHolder.title.setText(ps.get(position).getName());
listItemViewHolder.detail.setText(ps.get(position).getBirsthday());
listItemViewHolder.delet.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){
new AlertDialog.Builder(context).setTitle("确认删除吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 点击“确认”后的操作
PersonService personService = new PersonService(context);
personService.delete(ps.get(position));
ps.remove(position);
MyListViewAdapter.this.notifyDataSetChanged();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
});
return convertView;
}
//ViewHoider可以以内部类的形式写在里面以使代码更加简洁
public class ListItemViewHolder {
public TextView title;
public TextView detail;
public Button delet;
}
}
另外再介绍一下Button等控件放在Listview等的item中时,
Listview_
item如何获取点击事件
简单来说,就是
在item的
< RelativeLayout>中
android:descendantFocusability= "blocksDescendants"
和<Button>中
android:focusable = "false"
这是开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点。原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。
这时候就可以使用descendantFocusability来解决啦,API描述如下:
android:descendantFocusability
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.
Must be one of the following constant values.
![]()
该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。
属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
通常我们用到的是第三种,即在Item布局的根布局加上android:descendantFocusability=”blocksDescendants”的属性就好了。
另外开发中还遇到一个问题,listview的getView()方法会莫名其妙的执行3次,原来是listview的布局文件的问题:
<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
将android:layout_height="wrap_content"修改成:android:layout_height="fill_parent"就可以了。