Android中的自定义Adapter(继承自BaseAdapter)——与系统Adapter的调用方法一致——含ViewHolder显示效率的优化

  Android中很多地方使用的是适配器(Adapter)机制,那我们就要好好把这个Adapter利用起来,并且用出自己的特色,来符合我们自行设计的需要喽~~~

        下面先上一个例子,是使用ViewHolder进行显示效率优化过的工程:

        

[java]  view plain copy print ?
  1. package com.test.listviewsimpleadapter;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import android.app.AlertDialog;  
  9. import android.app.ListActivity;  
  10. import android.content.Context;  
  11. import android.content.DialogInterface;  
  12. import android.os.Bundle;  
  13. import android.util.Log;  
  14. import android.view.LayoutInflater;  
  15. import android.view.View;  
  16. import android.view.ViewGroup;  
  17. import android.widget.BaseAdapter;  
  18. import android.widget.Button;  
  19. import android.widget.ImageView;  
  20. import android.widget.ListView;  
  21. import android.widget.TextView;  
  22.   
  23. /* listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到listView的长 
  24.  * 度(这也是为什么在开始的第一张图特别的标出列表长度),然后根据这个长度,调用getView()逐 
  25.  * 一绘制每一行。如果你的getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。 
  26.  * 系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必 
  27.  * 须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。 
  28.  * getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的 
  29.  * 布局。我们用LayoutInflater的方法将定义好的main.xml文件提取成View实例用来显示。然后 
  30.  * 将xml文件中的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件 
  31.  * 上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定 
  32.  * 义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得 
  33.  * 要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面 
  34.  * 首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完 
  35.  * 这一行了。那 再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点 
  36.  * 了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点就OK了*/  
  37.   
  38. public class MyListView4 extends ListActivity {  
  39.   
  40.     private List<Map<String, Object>> mData;  
  41.   
  42.     @Override  
  43.     public void onCreate(Bundle savedInstanceState) {  
  44.         super.onCreate(savedInstanceState);  
  45.         mData = getData();  
  46.         MyAdapter adapter = new MyAdapter(this);  
  47.         setListAdapter(adapter);  
  48.     }  
  49.   
  50.     private List<Map<String, Object>> getData() {  
  51.         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
  52.   
  53.         Map<String, Object> map = new HashMap<String, Object>();  
  54.         map.put("title""G1");  
  55.         map.put("info""google 1");  
  56.         map.put("img", R.drawable.i1);  
  57.         list.add(map);  
  58.   
  59.         map = new HashMap<String, Object>();  
  60.         map.put("title""G2");  
  61.         map.put("info""google 2");  
  62.         map.put("img", R.drawable.i2);  
  63.         list.add(map);  
  64.   
  65.         map = new HashMap<String, Object>();  
  66.         map.put("title""G3");  
  67.         map.put("info""google 3");  
  68.         map.put("img", R.drawable.i3);  
  69.         list.add(map);  
  70.   
  71.         return list;  
  72.     }  
  73.   
  74.     // ListView 中某项被选中后的逻辑  
  75.     @Override  
  76.     protected void onListItemClick(ListView l, View v, int position, long id) {  
  77.         Log.v("MyListView4-click", (String) mData.get(position).get("title"));  
  78.     }  
  79.   
  80.     /** 
  81.      * listview中点击按键弹出对话框 
  82.      */  
  83.     public void showInfo() {  
  84.         new AlertDialog.Builder(this).setTitle("我的listview")  
  85.                 .setMessage("介绍...")  
  86.                 .setPositiveButton("确定"new DialogInterface.OnClickListener() {  
  87.                     @Override  
  88.                     public void onClick(DialogInterface dialog, int which) {  
  89.                     }  
  90.                 }).show();  
  91.     }  
  92.   
  93.     public final class ViewHolder {  
  94.         public ImageView img;  
  95.         public TextView title;  
  96.         public TextView info;  
  97.         public Button viewBtn;  
  98.     }  
  99.   
  100.     public class MyAdapter extends BaseAdapter {  
  101.   
  102.         private LayoutInflater mInflater;  
  103.   
  104.         public MyAdapter(Context context) {  
  105.             this.mInflater = LayoutInflater.from(context);  
  106.         }  
  107.   
  108.         @Override  
  109.         public int getCount() {  
  110.             // TODO Auto-generated method stub  
  111.             return mData.size();  
  112.         }  
  113.   
  114.         @Override  
  115.         public Object getItem(int arg0) {  
  116.             // TODO Auto-generated method stub  
  117.             return null;  
  118.         }  
  119.   
  120.         @Override  
  121.         public long getItemId(int arg0) {  
  122.             // TODO Auto-generated method stub  
  123.             return 0;  
  124.         }  
  125.   
  126.         @Override  
  127.         public View getView(int position, View convertView, ViewGroup parent) {  
  128.             // 显示优化(只要之前显示过的就可以不再再次从布局文件读取,直接从缓存中读取——ViewHolder的作用)  
  129.             // 其实是setTag和getTag中Tag的作用  
  130.             ViewHolder holder = null;  
  131.             if (convertView == null) {// 如果是第一次显示该页面(要记得保存到viewholder中供下次直接从缓存中调用)  
  132.   
  133.                 holder = new ViewHolder();  
  134.   
  135.                 convertView = mInflater.inflate(R.layout.main, null);  
  136.                 // 以下为保存这一屏的内容,供下次回到这一屏的时候直接refresh,而不用重读布局文件  
  137.                 holder.img = (ImageView) convertView.findViewById(R.id.img);  
  138.                 holder.title = (TextView) convertView.findViewById(R.id.title);  
  139.                 holder.info = (TextView) convertView.findViewById(R.id.info);  
  140.                 holder.viewBtn = (Button) convertView  
  141.                         .findViewById(R.id.view_btn);  
  142.                 convertView.setTag(holder);  
  143.   
  144.             } else {// 如果之前已经显示过该页面,则用viewholder中的缓存直接刷屏  
  145.   
  146.                 holder = (ViewHolder) convertView.getTag();  
  147.             }  
  148.                
  149.             //赋值语句不要写在上面,不然数据会重复

  1.             holder.img.setBackgroundResource((Integer) mData.get(position).get(  
  2.                     "img"));  
  3.             holder.title.setText((String) mData.get(position).get("title"));  
  4.             holder.info.setText((String) mData.get(position).get("info"));  
  5.   
  6.             holder.viewBtn.setOnClickListener(new View.OnClickListener() {  
  7.   
  8.                 @Override  
  9.                 public void onClick(View v) {  
  10.                     showInfo();  
  11.                 }  
  12.             });  
  13.             return convertView;  
  14.         }  
  15.     }  
  16. }  

        下面是将自定义的Adapter的构造方法定义为与系统的Adapter一致的工程,这样大家在实例化自定义的Adapter时可以按照实例化系统的Adapter的参数安排来进行哟~

        

[java]  view plain copy print ?
  1. package com.test.listviewsimpleadapter;  
  2.   
  3. import java.util.List;  
  4. import java.util.Map;  
  5. import android.app.AlertDialog;  
  6. import android.content.Context;  
  7. import android.util.Log;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.view.ViewGroup;  
  11. import android.widget.BaseAdapter;  
  12. import android.widget.Button;  
  13. import android.widget.CheckBox;  
  14. import android.widget.CompoundButton;  
  15. import android.widget.ImageView;  
  16. import android.widget.TextView;  
  17. import android.widget.CompoundButton.OnCheckedChangeListener;  
  18. /** 
  19.  * @author Himi 
  20.  *  
  21.  */  
  22. public class MySimpleAdapter extends BaseAdapter {  
  23.     private LayoutInflater mInflater;  
  24.     private List<Map<String, Object>> list;  
  25.     private int layoutID;  
  26.     private String flag[];  
  27.     private int ItemIDs[];  
  28.     public MySimpleAdapter(Context context, List<Map<String, Object>> list,  
  29.             int layoutID, String flag[], int ItemIDs[]) {  
  30.         Log.i("TAG","构造方法");  
  31.         this.mInflater = LayoutInflater.from(context);  
  32.         this.list = list;  
  33.         this.layoutID = layoutID;  
  34.         this.flag = flag;  
  35.         this.ItemIDs = ItemIDs;  
  36.     }  
  37.     @Override  
  38.     public int getCount() {  
  39.         // TODO Auto-generated method stub  
  40.         return list.size();  
  41.     }  
  42.     @Override  
  43.     public Object getItem(int arg0) {  
  44.         // TODO Auto-generated method stub  
  45.         return 0;  
  46.     }  
  47.     @Override  
  48.     public long getItemId(int arg0) {  
  49.         // TODO Auto-generated method stub  
  50.         return 0;  
  51.     }  
  52.     @Override  
  53.     public View getView(int position, View convertView, ViewGroup parent) {  
  54.         convertView = mInflater.inflate(layoutID, null);  
  55.         for (int i = 0; i < flag.length; i++) {//备注1  
  56.             if (convertView.findViewById(ItemIDs[i]) instanceof ImageView) {  
  57.                 ImageView iv = (ImageView) convertView.findViewById(ItemIDs[i]);  
  58.                 iv.setBackgroundResource((Integer) list.get(position).get(  
  59.                         flag[i]));  
  60.             } else if (convertView.findViewById(ItemIDs[i]) instanceof TextView) {  
  61.                 TextView tv = (TextView) convertView.findViewById(ItemIDs[i]);  
  62.                 tv.setText((String) list.get(position).get(flag[i]));  
  63.             }else{  
  64.                 //...备注2  
  65.                 Log.i("TAG","else");  
  66.             }  
  67.         }  
  68.         addListener(convertView);  
  69.         return convertView;  
  70.     }  
  71. /** 
  72.  * 童鞋们只需要将需要设置监听事件的组件写在下面这方法里就可以啦! 
  73.  * 别的不需要修改! 
  74.  * 备注3 
  75.  */  
  76.     public void addListener(View convertView) {  
  77.         ((Button)convertView.findViewById(R.id.btn)).setOnClickListener(  
  78.                 new View.OnClickListener() {  
  79.                     @Override  
  80.                     public void onClick(View v) {  
  81.                         new AlertDialog.Builder(LvSimpleAdapter.ma)  
  82.                         .setTitle("自定义通用SimpleAdapter")  
  83.                         .setMessage("按钮成功触发监听事件!")  
  84.                         .show();  
  85.                         Log.i("TAG","Button");  
  86.                     }  
  87.                 });  
  88.         ((CheckBox)convertView.findViewById(R.id.cb)).  
  89.         setOnCheckedChangeListener(new OnCheckedChangeListener() {  
  90.             @Override  
  91.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
  92.                 new AlertDialog.Builder(LvSimpleAdapter.ma)  
  93.                 .setTitle("自定义通用SimpleAdapter")  
  94.                 .setMessage("CheckBox成功触发状态改变监听事件!")  
  95.                 .show();  
  96.                 Log.i("TAG","CheckBox");  
  97.             }  
  98.         });  
  99.     }  
  100. }  
        以上代码的注释都比较详细,而且前面的Blog中也对Adapter进行过讲解,这边就不再说一遍啦~

        其中第二段代码中没有使用ViewHolder对显示效率进行优化,大家可以参考第一段稍稍改动一下就OK了哈~




实例:

package com.nautinus.activity;


import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.http.ParseException;
import org.json.JSONException;


import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;


import com.nautinus.bean.Constant;
import com.nautinus.bean.MachinesMaintain;
import com.nautinus.sop.RequestQuery;


public class OrderActivity extends Activity {


private ListView order_listView;
private Button accept_order_button;


private SimpleAdapter orderAdapter;
private BaseAdapter orderBaseAdapter;
private Map<String, Object> orderMap;
private ArrayList<MachinesMaintain> orderList;
private List<Map<String, Object>> orderAdapterData;
private RequestQuery requestQuery = new RequestQuery();



private static String user = "";


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
initUI();
initUser();
handler.post(orderRunnable);


}


@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// 重新取数
handler.post(orderRunnable);
}


private Handler handler = new Handler(new Handler.Callback() {


@Override
public boolean handleMessage(Message arg0) {
switch (arg0.arg1) {


case Constant.refresh:
handler.postDelayed(orderRunnable, 30000);
break;
default:
break;


}


return false;
}
});


private void initUser() {
TabHostActivity tabActivity = (TabHostActivity) getParent();
user = tabActivity.getUser();


}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.order, menu);
return true;
}


private void initUI() {
order_listView = (ListView) findViewById(R.id.order_listView);
// accept_order_button = (Button)
// findViewById(R.id.accept_order_button);
// accept_order_button.setOnClickListener(this);
}


/**
* 处理订单信息初始化

* @author Administrator

*/


private class QueryTask extends AsyncTask<Void, Void, Void> {


private Activity activity;
private ListView order_listView;


public QueryTask(Activity activity, ListView order_listView) {
this.activity = activity;
this.order_listView = order_listView;


}


@Override
protected Void doInBackground(Void... arg0) {
String sql = "SELECT * FROM MACHINES_MAINTAIN where receive_Flag=0  and ok_Flag=0  order by id";
System.out.println(sql);
// orderList = orderSopQuery.executeMaintainQuery(sql);

try {
orderList = requestQuery.executeMaintainQuery(sql);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// orderQueryData(sql);
return null;
}


@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);


if (orderList == null) {
Toast.makeText(OrderActivity.this, "暂无订单信息", Toast.LENGTH_SHORT)
.show();
} else {


orderBaseAdapter = new OrderListAdapter(OrderActivity.this,
orderList);
order_listView.setAdapter(orderBaseAdapter);


}


Message message = handler.obtainMessage();
message.arg1 = Constant.refresh;
message.sendToTarget();


// orderAdapter = new SimpleAdapter(
// OrderActivity.this,
// orderAdapterData,
// R.layout.activity_order_item,
// new String[] { "id", "roomCode", "groupCode", "image",
// "machcode", "reason" },
// new int[] { R.id.orderID, R.id.roomCode, R.id.groupCode,
// R.id.order_machine_pic, R.id.machcode, R.id.reason });
//
// order_listView.setAdapter(orderAdapter);


}


}


/**
* 处理接单按钮事务

* @author Administrator

*/


private class OrderTakenTask extends AsyncTask<Integer, Void, Boolean> {


private Activity activity;
private ListView order_listView;


public OrderTakenTask(Activity activity, ListView order_listView) {
this.activity = activity;
this.order_listView = order_listView;


}


@Override
protected Boolean doInBackground(Integer... arg0) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String receive_date = sdf.format(new Date());
// System.out.println(receive_date);


String sql = "update machines_maintain set Serviceman='" + user
+ "'" + ",Receive_flag=1" + ",receive_date='"
+ receive_date + "'" + " where id=" + arg0[0] + "";
boolean updateFlag = false;
int weizi = arg0[1];


System.out.println(sql);
System.out.println("list位置" + weizi);
try {
updateFlag = requestQuery.updateUser(sql);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


/**
* 接单成功移除数据
*/


if (updateFlag) {
orderList.remove(weizi);


for (int i = 0; i < orderList.size(); i++) {
System.out.println("移除后" + orderList.get(i).getId());


}


}


return updateFlag;
}


@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);


if (result) {


Toast.makeText(OrderActivity.this, "接单成功", Toast.LENGTH_SHORT)
.show();


orderBaseAdapter.notifyDataSetChanged();


} else {
Toast.makeText(OrderActivity.this, "接单失败", Toast.LENGTH_SHORT)
.show();


}


}


}




private Runnable orderRunnable = new Runnable() {


@Override
public void run() {
// TODO Auto-generated method stub


// Message message = handler.obtainMessage();
// message.arg1 = Constant.refresh;
// message.sendToTarget();
// 10秒循环一次
// handler.postDelayed(runnable, 10000);


new QueryTask(OrderActivity.this, order_listView).execute();


}
};


/**
* 自定义adapter

* @author Administrator

*/


public class OrderListAdapter extends BaseAdapter {

private LayoutInflater inflater;
private Context context; // 运行上下文
private ArrayList<MachinesMaintain> listData;


public OrderListAdapter(Context context,
ArrayList<MachinesMaintain> listData) {
super();
this.context = context;
this.listData = listData;
inflater = LayoutInflater.from(context);


}


@Override
public int getCount() {
// TODO Auto-generated method stub
return listData.size();
}


@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return listData.get(arg0);
}


@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}


public void refresh(ArrayList<MachinesMaintain> listData) {


this.listData = listData;
notifyDataSetChanged();


}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub


ViewHolder holder = null;


if (convertView == null) {


holder = new ViewHolder();


// 行布局模板
convertView = inflater.inflate(R.layout.activity_order_item,
null);
// 打到行布局模板中要显示的控件
holder.orderID = (TextView) convertView
.findViewById(R.id.orderID);
holder.roomCode = (TextView) convertView
.findViewById(R.id.roomCode);
holder.groupCode = (TextView) convertView
.findViewById(R.id.groupCode);
holder.order_machine_pic = (ImageView) convertView
.findViewById(R.id.order_machine_pic);
holder.machcode = (TextView) convertView
.findViewById(R.id.machcode);
holder.reason = (TextView) convertView
.findViewById(R.id.reason);


holder.accept_order_button = (Button) convertView
.findViewById(R.id.accept_order_button);


convertView.setTag(holder);


} else {
holder = (ViewHolder) convertView.getTag();


}


holder.accept_order_button.setTag(position);


MachinesMaintain one = (MachinesMaintain) listData.get(position);


// 给控件赋值
holder.orderID.setText(String.valueOf(one.getId()));
holder.roomCode.setText(one.getRoomCode());
holder.groupCode.setText(one.getGroupCode());
holder.machcode.setText(String.valueOf(one.getMachCode()));
holder.reason.setText(one.getStopReason());


switch (one.getState()) {
case Constant.open:
holder.order_machine_pic
.setImageResource(R.drawable.machinerun);
break;
case Constant.closed:
holder.order_machine_pic
.setImageResource(R.drawable.machineclose);
break;
case Constant.circule:
holder.order_machine_pic
.setImageResource(R.drawable.machinekongzhuan);
break;
case Constant.stop1:
holder.order_machine_pic.setImageResource(R.drawable.stop1);
break;
case Constant.stop2:
holder.order_machine_pic.setImageResource(R.drawable.stop2);
break;
case Constant.stop3:
holder.order_machine_pic.setImageResource(R.drawable.stop3);
break;
case Constant.stop4:
holder.order_machine_pic.setImageResource(R.drawable.stop4);
break;
case Constant.stop5:
holder.order_machine_pic.setImageResource(R.drawable.stop5);
break;
case Constant.stop6:
holder.order_machine_pic.setImageResource(R.drawable.stop6);
break;
case Constant.stop7:
holder.order_machine_pic.setImageResource(R.drawable.stop7);
break;
case Constant.stop8:
holder.order_machine_pic.setImageResource(R.drawable.stop8);
break;
default:
holder.order_machine_pic
.setImageResource(R.drawable.machinestop);
}


holder.accept_order_button
.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if ("".equals(user)) {


Toast.makeText(OrderActivity.this, "请先登录",
Toast.LENGTH_SHORT).show();
} else {
// 往数据库更新接单人和接单日期
Toast.makeText(OrderActivity.this,
"系统正在为你接单,请稍后", Toast.LENGTH_SHORT)
.show();
int cursor = Integer.parseInt(arg0.getTag()
.toString());

int id = orderList.get(cursor).getId();
System.out.println("cursor--" + cursor);
System.out.println("id----" + id);


new OrderTakenTask(OrderActivity.this,
order_listView).execute(id, cursor);


}


}
});


return convertView;


}


}


public final class ViewHolder {


TextView orderID;
TextView roomCode;
TextView groupCode;
ImageView order_machine_pic;
TextView machcode;
TextView reason;
Button accept_order_button;


}


}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值