前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3.CursorAdapter

3.CursorAdapter

作者头像
六月的雨
发布2018-05-14 11:52:10
1.3K0
发布2018-05-14 11:52:10
举报
文章被收录于专栏:Android开发指南Android开发指南

会话页面

点击菜单时编辑的按钮显示,其余的时候gone

ConversationUI

代码语言:javascript
复制
public class ConversationUI extends Activity implements OnItemClickListener, OnClickListener{
 private ListView listView;
 private Button btnNewMessage;
 private Button btnSelectAll;
 private Button btnSelectNull;
 private Button btnDeleteMsg;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_conversation);
 this.ctx = this;
		init();
		flushState();
		prepareData();
 }
 /**
	 * 要查询的列
	 */
 private String[] projection={
 "sms.body AS snippet",
 "sms.thread_id AS _id",//需要主键可是没有,可以起个别名
 "groups.msg_count AS msg_count",
 "address as address",
 "date as date"
 };
 /**
	 * 短信内容所在列的索引值 为 0
	 */
 private final int INDEX_BODY = 0;
 /**
	 * 会话ID所在列的索引值 为 1
	 */
 private final int INDEX_THREAD_ID = 1;
 /**
	 * 短信数量所在列的索引值 为 2
	 */
 private final int INDEX_MSG_COUNT = 2;
 /**
	 * 短信联系人电话所在列的索引值 为 3
	 */
 private final int INDEX_ADDRESS = 3;
 /**
	 * 短信日期所在列的索引值 为 4
	 */
 private final int INDEX_DATE = 4;
 /**
	 * 给listView 准备数据
	 */
 private void prepareData() {
 /*
		 * 查询数据库,如果数据太多了,会造成ANR异常,所 以,一般都会开子线程,查询数据,然后,用handler将结果,回传
		 */
  MyQueryHandler queryHandler = new MyQueryHandler(getContentResolver());
		queryHandler.startQuery(234, adapter, MyConstants.URI_CONVERSATION, projection, null, null, " date desc");//按日期倒序查询
 }
 private void init() {
		btnNewMessage = (Button) findViewById(R.id.btn_new_message_conversation);
		btnSelectAll = (Button) findViewById(R.id.btn_select_all_conversation);
		btnSelectNull = (Button) findViewById(R.id.btn_select_null_conversation);
		btnDeleteMsg = (Button) findViewById(R.id.btn_delete_message_conversation);
		btnNewMessage.setOnClickListener(this);
		btnSelectAll.setOnClickListener(this);
		btnSelectNull.setOnClickListener(this);
		btnDeleteMsg.setOnClickListener(this);
		listView = (ListView) findViewById(R.id.lv_conversation);
		adapter = new MyListAdapter(this, null);//可以先传个null
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(this);
		selectItemSet = new HashSet<Integer>();//删除时选中的集合
 }
 private boolean isEditState = false;
 private void flushState() {
 if(isEditState){//编辑状态
			btnNewMessage.setVisibility(View.GONE);
			btnSelectAll.setVisibility(View.VISIBLE);
			btnSelectNull.setVisibility(View.VISIBLE);
			btnDeleteMsg.setVisibility(View.VISIBLE);
 }else{//非编辑状态
			btnNewMessage.setVisibility(View.VISIBLE);
			btnSelectAll.setVisibility(View.GONE);
			btnSelectNull.setVisibility(View.GONE);
			btnDeleteMsg.setVisibility(View.GONE);
 }
 //判断listview 的条目是否有被选中,如果没有被选中的,btnSelectNull 和  btnDeleteMsg 应该处于不可用的状态 否则,是可用的状态
 if(selectItemSet.size()==0){// listview条目没有被选择
			btnSelectNull.setEnabled(false);
			btnDeleteMsg.setEnabled(false);
 }else{
			btnSelectNull.setEnabled(true);
			btnDeleteMsg.setEnabled(true);
 }
 // 根据 selectItemSet 集合当中的内容数量,改变 全选按钮的状态
 // 判断  selectItemSet 的size 和listView的条目数量,是否相同,如果相同,全选按钮,就不可用。
 if(selectItemSet.size() == adapter.getCount()){
			btnSelectAll.setEnabled(false);
 }else{
 // 否则,是可用的
			btnSelectAll.setEnabled(true);
 }
 }
 private MyListAdapter adapter ;
 public Context ctx;
 class MyListAdapter extends CursorAdapter{
 public MyListAdapter(Context context, Cursor c) {
 super(context, c);
 }
 @Override
 /**
		 * 当 conterView是null时,需要用户创建view 的时候调 
		 */
 public View newView(Context context, Cursor cursor, ViewGroup parent) {
 View view = View.inflate(ctx, R.layout.list_item_conversation,null);
 ViewHolder vh = new ViewHolder();
			vh.checkbox = (ImageView) view.findViewById(R.id.iv_checkbox_list_item);
			vh.face = (ImageView) view.findViewById(R.id.iv_face_list_item);
			vh.address = (TextView) view.findViewById(R.id.tv_address_list_item);
			vh.body = (TextView) view.findViewById(R.id.tv_body_list_item);
			vh.date = (TextView) view.findViewById(R.id.tv_date_list_item);
			view.setTag(vh);
 return view;
 }
 @Override
 /**
		 * 为itemview设置内容时调用
		 * view 即 newView 方法的返回值
		 */
 public void bindView(View view, Context context, Cursor cursor) {
 ViewHolder vh = (ViewHolder) view.getTag();
 //显示短信内容
			vh.body.setText(cursor.getString(INDEX_BODY));
 //显示日期:
 long when = cursor.getLong(INDEX_DATE);
 String dateStr;
 //使用系统工具类,判断是否是今天
 if(DateUtils.isToday(when)){
				dateStr = DateFormat.getTimeFormat(ctx).format(when);
 }else{
				dateStr = DateFormat.getDateFormat(ctx).format(when);
 }
			vh.date.setText(dateStr);
 //显示联系人地址:
 String number = cursor.getString(INDEX_ADDRESS);
 int msgcount = cursor.getInt(INDEX_MSG_COUNT);// 获得短信的数量
 String name = Tools.findNameByNumber(ctx, number);
 if(name == null){//表明无此联系人
				vh.address.setText(number+"("+msgcount+")");
 }else{
				vh.address.setText(name+"("+msgcount+")");
 }
 //显示联系人的头像:
 // 根据电话号码,查询联系人ID
 int contactId = Tools.findIDByNumber(ctx, number);
 // 如果 ID = -1 表明,无此联系人,此时,应设置一个 未知的联系人头像
 if(contactId == -1){
				vh.face.setBackgroundResource(R.drawable.ic_unknow_contact_picture);
 }else{
 // 根据ID 获得联系人头像,
 Bitmap bitmap = Tools.getFaceById(ctx, ""+contactId);
 //如果 bitmpa == null 表明,此联系人,无头像,应设置,一个联系人的默认的头像
 if(bitmap == null){
					vh.face.setBackgroundResource(R.drawable.ic_contact_picture);
 }else{
 //否则,将bitmap 设置为联系人的头像
					vh.face.setBackgroundDrawable(new BitmapDrawable(bitmap));
 }
 }
 /*
			 * 设置 checkBox
			 */
 //如果是编辑状态,显示checkBox,
 if(isEditState){
				vh.checkbox.setVisibility(View.VISIBLE);
 // 该条目对应的会话ID
 int threadId = cursor.getInt(INDEX_THREAD_ID);
 //判断集合当中,是否有该条目对应的会话ID,如果有,表示是选中状态,如果没有,是没选中状态。
 if(selectItemSet.contains(threadId)){
					vh.checkbox.setEnabled(true);
 }else{
					vh.checkbox.setEnabled(false);
 }
 }else{
 //否则,隐藏
				vh.checkbox.setVisibility(View.GONE);
 }
 }
 }
 /**
	 * 存储在编辑状态下,选中的listView的条目 
	 */
 private HashSet<Integer> selectItemSet;
 class ViewHolder{
 public ImageView checkbox;
 public ImageView face;
 public TextView address;
 public TextView body;
 public TextView date;
 }
 @Override
 /**
	 * 第一次点击menu按键时,调用,用于创建菜单选 项
	 */
 public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, ID_SEARCH, 0, "搜索");
		menu.add(0, ID_EDIT, 0, "编辑");
		menu.add(0, ID_CANCEL_EDIT, 0, "取消编辑");
 return true;
 }
 private final int ID_SEARCH=100;
 private final int ID_EDIT=101;
 private final int ID_CANCEL_EDIT=102;
 @Override
 /**
	 * 每次按menu按键的时候,调用,做一些准备工作
	 */
 public boolean onPrepareOptionsMenu(Menu menu) {
 if(isEditState){//如果是编辑状态
			menu.findItem(ID_EDIT).setVisible(false);
			menu.findItem(ID_SEARCH).setVisible(false);
			menu.findItem(ID_CANCEL_EDIT).setVisible(true);
 }else{
			menu.findItem(ID_EDIT).setVisible(true);
			menu.findItem(ID_SEARCH).setVisible(true);
			menu.findItem(ID_CANCEL_EDIT).setVisible(false);
 }
 return true;
 }
 @Override
 /**
	 * 当选择某一个菜单时,调用
	 */
 public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
 case ID_SEARCH:
 break;
 case ID_EDIT: // 编辑菜单
			isEditState = true;
			flushState();
 break;
 case ID_CANCEL_EDIT: //取消编辑
			isEditState = false;
 //清空集合
			selectItemSet.clear();
			flushState();
 break;
 }
 return true;
 }
 @Override
 /**
	 * 响应listview的条目点击事件
	 */
 public void onItemClick(AdapterView<?> parent, View view, int position,
 long id) {
 //通过adapter 获得cursor
 Cursor cursor = adapter.getCursor();
 //将cursor移动到对应的位置
		cursor.moveToPosition(position);
 //取得该位置对应的会话ID
 int threadId = cursor.getInt(INDEX_THREAD_ID);
 if (isEditState) {
 // 判断 集合中是否有该会话ID,如果有,就删除,如果没有,就添加
 if (selectItemSet.contains(threadId)) {
				selectItemSet.remove(threadId);
 } else {
				selectItemSet.add(threadId);
 }
 //刷新listview
			adapter.notifyDataSetChanged();
 //刷新按钮状态
			flushState();
 }else{
 String address = cursor.getString(INDEX_ADDRESS);
 Intent intent = new Intent(this,ConversationDetail.class);
			intent.putExtra("address", address);// 将当前条目对应的联系人电话号码,传递给会话详情页面
			startActivity(intent);
 }
 }
 @Override
 /**
	 * 响应按钮的点击事件
	 * @param v
	 */
 public void onClick(View v) {
 switch (v.getId()) {
 case R.id.btn_delete_message_conversation:
 //显示确认删除的对话框 
			showConfirmDeleteDialog();
 break;
 case R.id.btn_new_message_conversation:
 // 点击新建信息按钮时,响应
 Intent intent = new Intent(this,NewMessageUI.class);
			startActivity(intent);
 break;
 case R.id.btn_select_all_conversation: // 全选按钮
 Cursor cursor = adapter.getCursor();
			cursor.moveToPosition(-1);
 while(cursor.moveToNext()){
 int threadId = cursor.getInt(INDEX_THREAD_ID);
				selectItemSet.add(threadId); // set集合的特点:无序,不可重置,如果添加的内容之前已经有了,会覆盖。
 }
 //刷新listview
			adapter.notifyDataSetChanged();
 // 刷新状态
			flushState();
 break;
 case R.id.btn_select_null_conversation: // 取消选择的按钮
 //清空集合
			selectItemSet.clear();
 //刷新listview
			adapter.notifyDataSetChanged();
 // 刷新状态
			flushState();
 break;
 }
 }
 /**
	 * 显示确认删除的对话框 
	 */
 private void showConfirmDeleteDialog() {
 AlertDialog.Builder adb = new AlertDialog.Builder(this);
		adb.setTitle("清除短信");
		adb.setMessage("确认删除这些回忆吗?");
		adb.setNegativeButton("确认", new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 // 开子线程,删除短信,
 new Thread(new DeleteMsgRunnable()).start();
 // 显示删除短信的进度对话框
				showDeleteProgressDialog();
 }
 });
		adb.setPositiveButton("取消", null);
		adb.show();
 }
 private ProgressDialog proDlg;
 /**
	 * 显示删除短信的进度对话框
	 */
 protected void showDeleteProgressDialog() {
		proDlg =new ProgressDialog(this);
		proDlg.setTitle("正在删除短信");
 //设置 进度框 为水平显示的样式,
		proDlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
 // 设置进度条的最大值 = 集合的大小。
		proDlg.setMax(selectItemSet.size());
		proDlg.setButton("取消", new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
				isCancelDeleteMsg = true;
 }
 });
  // 给进度框添加,关闭时的回调 ,监听,监听的代码,会在UI线程中执行
		proDlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
 @Override
 public void onDismiss(DialogInterface dialog) {
				isEditState = false; 
				flushState();// 刷新页面状态
 System.out.println(selectItemSet);
				adapter.notifyDataSetChanged();// 刷新listview
 System.out.println("222::"+selectItemSet);
 }
 });
		proDlg.show();
 }
 /**
	 * 判断是否取消删除短信
	 */
 private boolean isCancelDeleteMsg;
 class DeleteMsgRunnable implements Runnable{
 @Override
 public void run() {
 // 遍历 selectItemSet 集合,根据会话ID,删除短信 
 for(Integer threadId : selectItemSet ){ // 用增强for循环 遍历 set集合 
 SystemClock.sleep(1000); // 会为显示效果正好,在此休眠一秒,
 if(isCancelDeleteMsg){
 break; // 跳出 for 循环
 }
 Tools.deleteMsgByThreadId(ctx,threadId);
				proDlg.incrementProgressBy(1);//让  proDlg 的水平进度条,增加刻度 
 }
 // 清空集合
			selectItemSet.clear();// 清空集合
 //关闭进度框
			proDlg.dismiss();
 // 将 isCancelDeleteMsg 复原
			isCancelDeleteMsg = false;
//			flushState();// 在子线程中不能更新UI
 }
 }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-11-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档