最近做的项目界面太复杂,不过后来发现可以用listview来简化xml代码量,但是后来发现虽然都是一条一条的界面显示内容,但是不是每一条都是一样的风格,所以就有了如题目一样的思考。嗯,直接把效果图展示出来吧,功能我还真没写,这只是一个测试的DEMO。不过思想已经表达很清晰了。
这是一个测试DEMO,所以按键功能等都没有写,就简单验证可以响应。
好吧,我们谈程序。我们分两步实现我们的功能,第一步实现同一种风格的item,只是这个item有很多控件;第二步实现不同风格的item。第一步很好做到,重写一个adapter,在我们重写的这个类里,我们把里面的getView方法覆盖掉,也就是按照我们设计的item上应该有多少控件都写到这里面来,因为listview的显示都是通过这个来设置View的,也就是getView参数中的第二个来设置View显示出每一个item的。参考下面代码:
/**
* 实现了一个适配器,用来显示自定义listview,这样的listview的每一个item都有很多控件,
* 每个控件也都能有自己的响应
*
* @author Tortoise
*
*/
public class MyItemAdapter extends BaseAdapter {
private Context context = null;
private List<Map<String, Object>> mData;
public MyItemAdapter(Context context, List<Map<String, Object>> data) {
// TODO Auto-generated constructor stub
this.context = context;
this.mData = data;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
// @Override
// public int getViewTypeCount() {
// // TODO Auto-generated method stub
// return 2;
// }
//
// @Override
// public int getItemViewType(int position) {
// // TODO Auto-generated method stub
// if(mData.get(position).get("title").toString().charAt(0)=='S'){
// return 0;
// }else{
// return 1;
// }
// }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder = null;
// ViewHolderOther viewHolderOther = null;
// if(getItemViewType(position)==0){
if(convertView == null){
viewHolder = new ViewHolder();
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.lineinspection_listview_item, null);
viewHolder.tv = (TextView)convertView.findViewById(R.id.tv_listview_item);
viewHolder.et = (EditText)convertView.findViewById(R.id.et_listview_item);
viewHolder.add = (Button)convertView.findViewById(R.id.btnadd_listview_item);
viewHolder.sub = (Button)convertView.findViewById(R.id.btnsub_listview_item);
viewHolder.remark = (Button)convertView.findViewById(R.id.btnremark_listview_item);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder)convertView.getTag();
}
viewHolder.tv.setText(mData.get(position).get("title").toString().substring(1));
viewHolder.et.setText(mData.get(position).get("info").toString());
viewHolder.add.setOnClickListener(new MyListener(position, 0));
viewHolder.sub.setOnClickListener(new MyListener(position, 1));
viewHolder.remark.setOnClickListener(new MyListener(position, 2));
// }else {
// if(convertView == null){
// viewHolderOther = new ViewHolderOther();
// LayoutInflater layoutInflater = LayoutInflater.from(context);
//
// convertView = layoutInflater.inflate(R.layout.lineinspection_listview_itemother, null);
//
// viewHolderOther.tv = (TextView)convertView.findViewById(R.id.tv_listview_itemother);
// viewHolderOther.et = (EditText)convertView.findViewById(R.id.et_listview_itemother);
// viewHolderOther.remark = (Button)convertView.findViewById(R.id.btnadd_listview_itemother);
//
// convertView.setTag(viewHolderOther);
// }else{
// viewHolderOther = (ViewHolderOther)convertView.getTag();
// }
//
// viewHolderOther.tv.setText(mData.get(position).get("title").toString());
// viewHolderOther.et.setText(mData.get(position).get("info").toString());
// viewHolderOther.remark.setOnClickListener(new MyListener(position, 2));
// }
return convertView;
}
//Button响应
private class MyListener implements OnClickListener{
private int position;
private int serial;
public MyListener(int position, int serial) {
// TODO Auto-generated constructor stub
this.position = position;
this.serial = serial;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (serial) {
case 0:
Toast.makeText(context, "第"+position+"行的第一个按钮", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(context, "第"+position+"行的第二个按钮", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(context, "第"+position+"行的第三个按钮", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
/**
* 对应每一个item的控件
* @author Tortoise
*
*/
private static class ViewHolder{
TextView tv;
EditText et;
Button add;
Button sub;
Button remark;
}
// private static class ViewHolderOther{
// TextView tv;
// EditText et;
// Button remark;
// }
}
MyItemAdapter的构造函数我传入两个参数,第一个是上下文,是必备的;第二个是数据源,我们都知道也就是我们要显示的数据,只是我这里数据我存在一个list里面,是一样的。重点看getView这个函数,这个函数重写了父类方法,让每一个item加载的显示都是我定义的一个xml,这个xml里我把我要的控件都加进去了。同时,还要对控件进行响应,比方说按钮要添加监听等,其实思路很简单,也很好理解。
上面就实现了同一种风格的item的listview,那不同风格的差异在哪里呢?其实我们想想肯定是对应不同的item我们加载不同的xml,对不同的xml实现不同的响应而已。事实也的确如此。但是我们除了要做第二套风格的item的xml之外,还要重写两个函数,一个是getViewTypeCount,这个是获取有几种风格的item;另一个是getItemViewType,这个是设置不同item对应不同风格。这个理解好理解,但是我们怎么知道我们那个要设置成什么样的风格呢?我这里提供了一个简单的思路,比方说我给第一种风格的item的数据源都加上一个字符“S”,这样我就可以每次设置风格的时候先获取数据源的第一个字符,如果是“S”,我们就设置成第一种风格的item,如果不是就设置成第二种风格,同理也可以设置三种,四种以及多种的风格的item。不过这样我们改变了数据源,这不是问题,我们加载数据源显示的时候,把我们人为加上去的字符去掉就可以了。
代码我就不贴了,把上面的代码中的注释去掉就行了。
我的工程可以在这里下载:http://download.csdn.net/detail/u012321815/8533743