Android应用开发之多选删除之二

来源:互联网 发布:阎良广电网络怎么样 编辑:程序博客网 时间:2024/05/17 06:20

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ 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案例代码下载

点我下载源码

原创粉丝点击