这段时间写了一个ListView,并且该ListView里面的每一项都需要有一个按钮且点击按钮会响应相应的操作。以前写ListView的时候都是直接用ArrayAdapter或者SimpleAdapter,但是这次这次因为有一个按钮需要响应就不能这么做了。所以需要自己写一个继承自BaseAdapter的类。
这是我写的类:
class MyAdapter extends BaseAdapter
{
private Context context;
private LayoutInflater inflater;
private int layoutID;
private int imageResources[];
private int buttonResources[];
private List<HashMap<String,int[]>> list;
private String flags[];
private int itemIDs[];
class Holder
{
ImageView image;
ImageButton button;
}
public MyAdapter(Context context,int layoutID , List<HashMap<String,int[]>> list, String[] flag , int[] itemIDs)
{
super();
this.context=context;
this.layoutID=layoutID;
this.list=list;
this.flags=flags;
this.itemIDs=itemIDs;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
if(convertView==null)
{
//this.inflater=LayoutInflater.from(context);
//this.inflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.inflater=getLayoutInflater();
convertView=inflater.inflate(layoutID, null);
holder.image=(ImageView)convertView.findViewById(R.id.iv_image);
holder.button=(ImageButton)convertView.findViewById(R.id.btn_take);
convertView.setTag(holder);
}
else
holder=(Holder)convertView.getTag();
int resources[]=this.list.get(position).get("resource");
holder.image.setImageDrawable(context.getResources().getDrawable(resources[0]));
final int pos=position;
holder.button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
//String str=String.format("%d", position);
// TODO Auto-generated method stub
Toast.makeText(context, ""+pos, Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
BaseAdapter类是一个最基本的适配器,用于连接ListView Spinner等控件与数据。如果要重写一个BaseAdapter,有几个方法是必须要重写的: public int getCount() public Object getItem(int arg0) public Object getItemID(int arg0) public View getView(int position, View convertView, ViewGroup parent),其中最重要的就是getCount()和getView()这两个函数。 至于像构造函数和类里面的其他变量则是根据自己具体的需要来设定的。
在ListView中显示每一项的内容的过程是这样的:
首先调用getCount()函数得到一共要显示多少行。如果这个函数return 0,那就会一行都不显示。而至于每一行具体显示什么内容则是通过getView函数来实现的。
public View getView(int position, View convertView, ViewGroup parent)
- /**
- * 这个方法getView(),是用来逐一绘制每一条item
- * *
- * @param position position就是位置从0开始
- * @param convertView convertView是Spinner,ListView中每一项要显示的view
- * @param parent parent就是父窗体了,也就是Spinner,ListView,GridView了
- * @return 通常return 的view也就是convertView
convertView就是我们最后要显示的每一项里面内容,如果convertView是第一次绘制,为一个null值,那么我们需要通过LayoutInflater将xml文件里面的布局导入到convertView中。只是convertView=inflater.inflate(layoutID, null);这句为什么第二个参数必须是null不然就会崩,这一点我始终没有搞清楚。有知道的大虾麻烦给我解解惑。
接下来我们就将控件与对应的ID绑定起来。最后通过setTag()把将我们自己设定的Holder类与convertView绑定起来。
如果我们不是第一次绘制,这是converView不是null,那我们可以直接调用getTag()函数将其与我们设定的Holder类绑定起来。
绑定好之后,我们就可以对这些具体的控件进行具体的处理了。包括给ImageView设置图像啊,给Button写响应函数之类的啊。
看到这里,如果是第一次遇到这个问题的同学可能对代码中Holder类和getTag() setTag()两个函数不太理解,其实特别简单。
Holder这个类其实就是我们将ListView里面每一项的控件全部封装起来,而这么做的原因就是因为setTag就是将每一项里面的全部控件全部写入到convertView中去,这样每一项的内容才能显示(inflate函数只是将对应的xml载入到view中,但没有显示出来,要显示出来必须要用setTag函数)。而getTag()就返回的是convertView里面的全部控件内容,其返回值是一个Object对象,只要将这个返回值赋值给一个Holder我们就可以方便的对这些控件进行设置了。