zoukankan      html  css  js  c++  java
  • Android应用开发之多选删除之二

    传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

    MultiSelectDeleteActivity.java

    package cn.lynn.multisel;
    
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.app.ProgressDialog;
    import android.content.ContentUris;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.provider.ContactsContract.Contacts;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.ListView;
    import android.widget.TextView;
    
    public class MultiSelectDeleteActivity extends Activity implements OnClickListener, OnItemClickListener {
    
        private static final String TAG = "MultiSelectDeleteActivity";
        private ListView delList;
        private Button delBtn;
        private Button canBtn;
        private CheckBox selAllChk;
        private Cursor cursor;
        private int count;
        private DeleteListAdapter delListAdapter;
        // 期望查询的联系人字段
        private static final String[] PROJECTION = new String[] {Contacts._ID, Contacts.DISPLAY_NAME};
        private static final int CONTACTS_ID_INDEX = 0;
        private static final int DISPLAY_NAME_INDEX = 1;
        
        // 用于保存记录是否被选中的状态,这里定义为静态变量是为了防止Home键切换之后普通成员变量无法保存切换之前的数据
        private static HashMap<Integer, Boolean> statusMap;
    
        /**
         * 用于删除的联系人记录的封装类
         */
        private final class ViewHolder {
            TextView nameTxt;
            CheckBox selectChk;
        }
        
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            statusMap = new HashMap<Integer, Boolean>();
    
            delList = (ListView) findViewById(R.id.del_list);
            delBtn = (Button) findViewById(R.id.del_btn);
            canBtn = (Button) findViewById(R.id.can_btn);
            selAllChk = (CheckBox) findViewById(R.id.select_all).findViewById(R.id.select_all_chk);
            
            delList.setOnItemClickListener(this);
            delBtn.setOnClickListener(this);
            canBtn.setOnClickListener(this);
            selAllChk.setOnClickListener(new SelectAllClickListener());
        }
        
        @Override
        protected void onDestroy() {
            super.onDestroy();
            statusMap.clear();
            // 静态变量,提示和加快GC回收它,否则有很大可能要等到VM Full gc时才能回收
            statusMap = null;
        }
        
        @Override
        public void onResume() {
            super.onResume();
            refreshData();
        }
        
        @Override
        protected void onPause() {
            super.onPause();
            // 保存切换之前的记录数
            count = cursor.getCount();
        }
    
        /**
         * 查询联系人数据库记录
         */
        private void refreshData() {
            selAllChk.setEnabled(false);
            delBtn.setEnabled(false);
            cursor = getContentResolver().query(Contacts.CONTENT_URI, PROJECTION, null, null, null);
            if(cursor.getCount() > 0) {
                selAllChk.setEnabled(true);
                // Home键切换到Contacts应用增加联系人
                if(count < cursor.getCount()) {
                    selAllChk.setChecked(false);
                }
            }
            if(statusMap.containsValue(true)) {
                delBtn.setEnabled(true);
            }
            Log.i(TAG, "cursor= " + cursor);
            delListAdapter = new DeleteListAdapter(this, cursor);
            delList.setAdapter(delListAdapter);
            delListAdapter.notifyDataSetChanged();
        }
        
        /**
         * 单独为全选CheckBox设置点击事件的监听器,因为它的布局是从当前Activity的子布局文件R.id.select_all中加载而来,
         * 这样做的好处是防止多个按钮都在Activity布局层次上监听同类点击事件时出现“屏蔽”现象
         */
        private class SelectAllClickListener implements OnClickListener {
            @Override
            public void onClick(View v) {
                if(selAllChk.isChecked()) {
                    for (int i = 0; i < delListAdapter.getCount(); i++) {
                        statusMap.put(i, true);
                        delListAdapter.cursor.moveToPosition(i);
                        delListAdapter.idSet.add(delListAdapter.cursor.getInt(CONTACTS_ID_INDEX) + "");
                    }
                    delBtn.setEnabled(true);
                } else {
                    for (int i = 0; i < delListAdapter.getCount(); i++) {
                        statusMap.put(i, false);
                    }
                    delListAdapter.idSet.clear();
                    delBtn.setEnabled(false);
                }
                // 数据发生变化,通知UI更新
                delListAdapter.notifyDataSetChanged();
            }
            
        }
    
        /**
         * 为ListView设置删除联系人记录的Adapter
         */
        private class DeleteListAdapter extends BaseAdapter {
            Cursor cursor;
            // 保存被选中的联系人Id
            HashSet<String> idSet;
            
            public DeleteListAdapter(Context context, Cursor cursor) {
                this.cursor = cursor;
                idSet = new HashSet<String>();
                for (int i = 0; i < cursor.getCount(); i++) {
                    // 初始化新的联系人记录为未选中的状态
                    if(statusMap.containsKey(i)) continue;
                    statusMap.put(i, false);
                }
                Log.i(TAG, "statusMap size=" + statusMap.size());
            }
    
            @Override
            public int getCount() {
                return cursor.getCount();
            }
    
            @Override
            public Object getItem(int position) {
                if(cursor.moveToPosition(position)) {
                    return cursor;
                } else {
                    return null;
                }
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
    
            // 这里启用了convertView缓存,并创建ViewHolder类以提高ListView执行效率
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder = null;
                if(convertView == null) {
                    convertView = LayoutInflater.from(MultiSelectDeleteActivity.this).inflate(R.layout.list_item, null);
                    holder = new ViewHolder();
                    holder.nameTxt = (TextView) convertView.findViewById(R.id.name_txt);
                    holder.selectChk = (CheckBox) convertView.findViewById(R.id.select_chk);
                    convertView.setTag(holder);
                }
                cursor.moveToPosition(position);
                holder = (ViewHolder) convertView.getTag();
                final String name = cursor.getString(DISPLAY_NAME_INDEX);
                holder.nameTxt.setText(name);
                holder.selectChk.setChecked(statusMap.get(position));
                if(statusMap.get(position)) {
                    // 存储选中状态的记录的Id
                    idSet.add(cursor.getInt(CONTACTS_ID_INDEX)+"");
                } else {
                    // 移除非选中状态的记录的Id
                    idSet.remove(cursor.getInt(CONTACTS_ID_INDEX)+"");
                }
                return convertView;
            }
        }
    
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Log.i(TAG, "onItemClick...");
            ViewHolder holder = (ViewHolder) view.getTag();
            holder.selectChk.toggle();
            statusMap.put(position, holder.selectChk.isChecked());
            delListAdapter.notifyDataSetChanged();
            // 判断是否有记录没被选中,以便更改全选CheckBox的勾选状态
            if(statusMap.containsValue(false)) {
                selAllChk.setChecked(false);
            } else {
                selAllChk.setChecked(true);
            }
            Log.i(TAG, "------------statusMap data--------------");
            for (Map.Entry<Integer, Boolean> entry: statusMap.entrySet()) {
                Log.i(TAG, "statusMap key=" + entry.getKey() + ", value= " + entry.getValue());
            }
            
            // 判断是否有记录被选中,以便更改删除Button的可用状态
            if(statusMap.containsValue(true)) {
                delBtn.setEnabled(true);
            } else {
                delBtn.setEnabled(false);
            }
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            // 删除按钮
            case R.id.del_btn:
                new AlertDialog.Builder(this)
                    .setTitle(R.string.clearConfirmation_title)
                    .setMessage(R.string.clearConfirmation)
                    .setNegativeButton(android.R.string.cancel, null)
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                        @SuppressWarnings("unchecked")
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            final ProgressDialog progressDialog = ProgressDialog.show(MultiSelectDeleteActivity.this, getString(R.string.clearProgress_title), "", true, false);
                            final AsyncTask<HashSet<String>, Integer, Cursor> deleteWork = new AsyncTask<HashSet<String>, Integer, Cursor>() {
                                Uri uri = null;
                                @Override
                                protected Cursor doInBackground(HashSet<String> ... params) {
                                    // 后台工作线程执行删除联系人记录操作
                                    HashSet<String> ids = params[0];
                                    for (String id : ids) {
                                        Log.i(TAG, "deleted id= " + id);
                                        uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(id));
                                        MultiSelectDeleteActivity.this.getContentResolver().delete(uri, null, null);
                                    }
                                    Log.i(TAG, "doInBackground statusMap size=" + statusMap.size());
                                    // 清除所有被选中的联系人Id
                                    delListAdapter.idSet.clear();
                                    cursor = MultiSelectDeleteActivity.this.getContentResolver().query(Contacts.CONTENT_URI, PROJECTION, null, null, null);
                                    return cursor;
                                }
                                
                                // 删除操作的实时进度,本案例不对此做任何处理
                                @Override
                                protected void onProgressUpdate(Integer... values) {
                                    super.onProgressUpdate(values);
                                }
                                
                                // 删除操作执行完毕后回调此方法,可以得到处理结果,并通知UI更新
                                @Override
                                protected void onPostExecute(Cursor result) {
                                    super.onPostExecute(result);
                                    Log.i(TAG, "result getCount= " + result.getCount());
                                    if(result.getCount() == 0){
                                        // 删除全部记录后,全选CheckBox应该被禁用(不能再点击),当有新记录加入时才可以重新启用它
                                        selAllChk.setChecked(false);
                                        selAllChk.setEnabled(false);
                                    }
                                    delBtn.setEnabled(false);
                                    statusMap.clear();
                                    // 删除操作完成后,重置剩下的记录为未选中状态
                                    for (int i = 0; i < result.getCount(); i++) {
                                        statusMap.put(i, false);
                                    }
                                    delListAdapter.cursor = result;
                                    delListAdapter.notifyDataSetChanged();
                                    progressDialog.dismiss();
                                }
                            };
                            progressDialog.show();
                            deleteWork.execute(delListAdapter.idSet);
                        }
                    })
                    .setCancelable(true)
                    .create()
                    .show();
                break;
                
             // 取消按钮
            case R.id.can_btn:
                
                break;
            }
        }
    }

    3案例效果展示

      

      

    4案例代码下载

    点我下载源码

  • 相关阅读:
    2015第18周日
    CreateProcess的使用方法
    A ResourcePool could not acquire a resource from its primary factory or source
    ThreadPool.QueueUserWorkItem的性能问题
    Cucumber 入门一
    菜鸟版JAVA设计模式-从抽象与实现说桥接模式
    ServiceStack.Hello——跨平台.net REST api服务搭建
    android看不见main函数怎么办?程序异常了,能够不提示“xxx软件停止执行”吗?
    深入探讨this指针
    问卷星调查学生对《算法》教学的建议与反馈
  • 原文地址:https://www.cnblogs.com/innosight/p/3271152.html
Copyright © 2011-2022 走看看