上一次,我们通过ActionBar删除整个短信会话,但在实际使用中,我们还需要删除选中的某条记录,而非会话下所有短信,在这一篇文章中,我们就一起来该如何做吧,运行效果如下:
首先,为使用上下文菜单,需要在ShowSessionMessagesActivity中重写上下文菜单的相关方法,包括onCreateContextMenu()和onContextItemSelected(),前者用于创建上下文菜单,加载相应的定义上下文菜单选项的文件,后者定义了上下文菜单选项被选中的处理方法,先来看一下onCreateContextMenu()的实现吧。
//加载上下文菜单文件,创建上下文菜单,当某条短信被点击时弹出选项
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
//通过xml文件来配置上下文菜单选项
MenuInflater mInflater = getMenuInflater();
mInflater.inflate(R.menu.show_session_messages_context_menu, menu);
super.onCreateContextMenu(menu, v, menuInfo);
}
在此方法中,加载了上下文菜单的定义文件,即show_session_messages_context_menu.xml,该xml文件中定义了上下文菜单的选项,文件所在目录与OptionMenu一样,都是工程下的res\menu,定义的方式也与OptionMenu一样,下面看一下xml文件的定义。
通过文件的定义,我们可以看到上下文菜单中包含了两个选项,分别用于删除和转发,item的id属性在onContextItemSelected()中需要用到,而title属性为选项在上下文菜单中显示时的文本内容。
在加载了上下文菜单之后,我们还需要定义当上下文菜单中的某个选项被点击时对应的处理方法,为此,我们必须重写onContextItemSelected()方法,当上下文菜单选项被选中时系统将会调用此方法,重写后的onContextItemSelected()定义如下:
//根据被点击的菜单项执行对应的操作
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo)item.getMenuInfo();
// 获取选中行位置
position = contextMenuInfo.position;
switch (item.getItemId()) {
//删除短信
case R.id.show_session_messages_context_menu_delete:
//弹出提示窗口
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("温馨提示");
builder.setMessage("删除此条信息?");
builder.setPositiveButton("确定",new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialoginterface, int i){
//删除被长按选中的短信
getContentResolver().delete(Uri.parse(
"content://sms/"+infos.get(position).getId()),null, null);
/* * 信息删除成功后,刷新显示新的短信列表
* 在调用notifyDataSetChanged()方法通知数据更新时,为了让数据显示实时刷新,
* 需要先对Adapter中的数据存储对象重新赋值,此处调用getSessionMessages()
* 方法,从数据库查询删除短信后的当前短信会话记录,存储到数据对象infos中*/
infos = sessionMessagesAdapter.getSessionMessages(threadId);
//若删除的短信是当前会话中的最后一条,删除成功后跳转到短信会话主界面
if(infos!=null && infos.isEmpty()){
Intent intent = new Intent();
intent.setClass(ShowSessionMessagesActivity.this,MainActivity.class);
ShowSessionMessagesActivity.this.startActivity(intent);
}
sessionMessagesAdapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("取消",null);
builder.show();
break;
case R.id.show_session_messages_context_menu_forward:
Toast.makeText(this, "转发信息", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(this, "未定义的上下文菜单项", Toast.LENGTH_SHORT).show();
break;
}
return super.onContextItemSelected(item);
}
在这个方法中,我们通过调用传递过来的参数MenuItem的getItemId(),可以得到
被点击的上下文菜单的item在show_session_messages_context_menu.xml所对应定义的id值,根据id值判断用户选择的是哪个选项,从而采取不同的处理方法。在这里,我们依次检查了在上下文菜单文件中定义的选项,当用户长按某条短信触发了上下文菜单,当选择删除短信时,我们将删除这条被选中的短信记录,在选择转发或其他操作时,弹出对应的提示框,另外,在成功删除短信记录后,检查删除的是否为最后一条短信,若是,该短信会话为空,需要跳转页面到短信会话主界面。我们下面来详细看一下删除单条短信的实现方法。
首先,我们需要得到被选中的短信在列表中的位置,我们可以通过MenuItem对象来获取,声明语句如下:
AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo)item.getMenuInfo();
position = contextMenuInfo.position;//position变量为新增全局int变量
position就是短信在列表中的位置,接着,参照我们在上一篇文章中删除短信会话的方法,那时是通过ContentResolver的delete()方法来执行删除操作的,这次我们也可以使用相同的方法,传入对应的URI和删除需要的短信id参数就可以了,但是这样做还有一个问题,我们之前删除短信会话是在Adapter适配器中执行的,执行删除操作的短信会话id可以通过ShowSessionMessagesAdapter中用来存储短信会话列表的本地变量List
infos = sessionMessagesAdapter.getSessionMessages(threadId);
另外,我们使用了AlertDialog,在用户点击删除选项时,在执行删除操作之前弹出确认提示框,防止误操作。
最后,为令上下文菜单生效,我们还需要为短信列表显示控件注册上下文菜单事件,在onCreate()方法中增加声明如下:
registerForContextMenu(sessionMessagesListView);
这样,我们就实现了用上下文菜单删除选中的单条短信记录的功能了。