使用ListView时遇到的问题

来源:互联网 发布:淘宝加入购物车 找不到 编辑:程序博客网 时间:2024/06/05 19:38

这周练习ListView时遇到了一个问题,从数据库中查询出的数据绑定到LIstView上,长按某个item进行删除操作,每次点击item取得的id都不对,调了半天终于找到了原因,关键是自己对自定义的BaseAdapter没有理解深刻。

先说说ListView使用BaseAdapter的优化技巧。

一般当系统提供的Adapter无法满足项目需求时,就需要自己定制一个Adpater,实现getView等方法给每一个item一个样式,getView方法就好比每一个Item对象绘制到屏幕上时会对我发一个消息:"嘿,boy,我要出现在你面前了,但是我还不知道你希望我长啥样,请帮忙在getView方法帮我选一个样式!"。于是我们就帮item绘制一个新的样式布局。但是每次item这家伙要我们帮忙的时候,都重新绘制布局对象,显然会对系统性能产生影响,所以我们需要优化一下,把布局缓存起来,这里官方推荐的是采用ViewHolder对象,说白了就是一个单例模式,判断为空时则新建一个,并存到某个缓存中,不为空,则直接从缓存取出来,丢给item.

具体代码如下:

public class NoteListAdapter extends BaseAdapter {private List<Note> noteList = null;private LayoutInflater layoutInflater;private static final String TAG = NoteListAdapter.class.getSimpleName();public NoteListAdapter(Context context, List<Note> list) {this.noteList = list;layoutInflater = LayoutInflater.from(context);}public void setNoteList(List<Note> noteList) {this.noteList = noteList;}    // 返回顯示的List中Item的個數@Overridepublic int getCount() {return noteList.size();}//得到指定位置的Item對象@Overridepublic Object getItem(int position) {return noteList.get(position);}//得到Item的Id@Overridepublic long getItemId(int position) {return position;}@SuppressLint("SimpleDateFormat")@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Log.i(TAG, "getView被調用");ViewHolder holder;if (convertView == null) {convertView = layoutInflater.inflate(R.layout.note_list, null);holder = new ViewHolder();TextView tv = (TextView) convertView.findViewById(R.id.tv_info_title);holder.setInfotitle(tv);TextView tvtime = (TextView) convertView.findViewById(R.id.tv_info_time);holder.setInfotime(tvtime);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}if(!TextUtils.isEmpty(noteList.get(position).getTitle().toString().trim())){    long id = noteList.get(position).getId();    String title = noteList.get(position).getTitle();    Date date = noteList.get(position).getCreateDate();    Log.i(TAG, "從Adapter查出來的Id"+id);    holder.getInfotitle().setText(title);    SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");    holder.getInfotime().setText(format.format(date));        }return convertView;}private class ViewHolder {private TextView infotitle;private TextView infotime;public TextView getInfotitle() {return infotitle;}public void setInfotitle(TextView infotitle) {this.infotitle = infotitle;}public TextView getInfotime() {return infotime;}public void setInfotime(TextView infotime) {this.infotime = infotime;}}  }

在这里有个地方开始没有注意

 long id = noteList.get(position).getId();

这一句代码id是根据postition的位置来得到的。

于是在我点击item时取得的id应该是通过参数中position变量获取而不是参数中的id变量

先给出开始时的错误代码:

//点击@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {Intent intent = new Intent(this,NoteAddActivity.class);//这个地方取到的id不正确
intent.putExtra("id", id);intent.putExtra("edit", true);startActivity(intent);}

正确的代码如下:

//点击@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {Intent intent = new Intent(this,NoteAddActivity.class);id = noteList.get(position).getId();intent.putExtra("id", id);intent.putExtra("edit", true);startActivity(intent);}

另外当在上下文菜单获取item的id时只有一个MenuItem对象参数,这时候应该借助AdapterView.AdapterContextMenuInfo对象获取id

代码片段如下:

@Overridepublic boolean onContextItemSelected(MenuItem item) {//獲得上下文菜單信息    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); //點擊的Item的IDfinal Long MID = noteList.get(info.position).getId();switch (item.getItemId()) {//刪除case ITEM1:service = DbService.getInstance(this);AlertDialog.Builder builder = new AlertDialog.Builder(ManagerActivity.this);builder.setTitle("提示").setIcon(android.R.drawable.ic_dialog_alert).setMessage("確定刪除嗎?").setNegativeButton("否", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).setPositiveButton("是", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Runnable deleteNote = new Runnable() {@Overridepublic void run() {//發送消息給handlerservice.deleteNote(MID);Toast.makeText(ManagerActivity.this, "刪除成功", Toast.LENGTH_SHORT).show();Log.i(TAG, "刪除的ID"+MID);    noteList = service.loadAllNote();    ma.setNoteList(noteList);ma.notifyDataSetChanged();}};myHandler.post(deleteNote);}}).create().show();return true;
最后注意的地方是adpter中的list数据如果有变化,需要把新的list对象set给adpter对象,后面别忘了加上notifyDataSetChanged()方法重新绘制。


原创粉丝点击