Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android應用開發之多選刪除之二

Android應用開發之多選刪除之二

編輯:關於Android編程

MultiSelectDeleteActivity.java

[java] 
package cn.lynn.multisel; 
 
import java.util.HashMap; 
import java.util.HashSet; 
 
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 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(); 
    } 
 
    /**
     * 查詢聯系人數據庫記錄
     */ 
    private void refreshData() { 
        selAllChk.setEnabled(false); 
        cursor = getContentResolver().query(Contacts.CONTENT_URI, PROJECTION, null, null, null); 
        if(cursor.getCount() > 0) { 
            selAllChk.setEnabled(true); 
        } 
        Log.i(TAG, "cursor= " + cursor); 
        delListAdapter = new DeleteListAdapter(this, cursor); 
        delList.setAdapter(delListAdapter); 
    } 
     
    /**
     * 單獨為全選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>(); 
            Log.i(TAG, "statusMap size=" + statusMap.size()); 
            for (int i = 0; i < cursor.getCount(); i++) { 
                // 初始化新的聯系人記錄為未選中的狀態  
                if(statusMap.containsKey(i)) continue; 
                statusMap.put(i, false); 
            } 
        } 
 
        @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); 
        } 
        // 判斷是否有記錄被選中,以便更改刪除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, "id= " + id); 
                                    uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(id)); 
                                    MultiSelectDeleteActivity.this.getContentResolver().delete(uri, null, null); 
                                } 
                                delListAdapter.idSet.removeAll(ids); 
                                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); 
                                }  
                                delListAdapter.cursor = result; 
                                delListAdapter.notifyDataSetChanged(); 
                                progressDialog.dismiss(); 
                            } 
                        }; 
                        progressDialog.show(); 
                        deleteWork.execute(delListAdapter.idSet); 
                    } 
                }) 
                .setCancelable(true) 
                .create() 
                .show(); 
            break; 
             
         // 取消按鈕  
        case R.id.can_btn: 
             
            break; 
        } 
    } 

package cn.lynn.multisel;

import java.util.HashMap;
import java.util.HashSet;

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 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();
    }

    /**
     * 查詢聯系人數據庫記錄
     */
    private void refreshData() {
        selAllChk.setEnabled(false);
        cursor = getContentResolver().query(Contacts.CONTENT_URI, PROJECTION, null, null, null);
        if(cursor.getCount() > 0) {
            selAllChk.setEnabled(true);
        }
        Log.i(TAG, "cursor= " + cursor);
        delListAdapter = new DeleteListAdapter(this, cursor);
        delList.setAdapter(delListAdapter);
    }
   
    /**
     * 單獨為全選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>();
            Log.i(TAG, "statusMap size=" + statusMap.size());
            for (int i = 0; i < cursor.getCount(); i++) {
                // 初始化新的聯系人記錄為未選中的狀態
                if(statusMap.containsKey(i)) continue;
                statusMap.put(i, false);
            }
        }

        @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);
        }
        // 判斷是否有記錄被選中,以便更改刪除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, "id= " + id);
                                    uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.valueOf(id));
                                    MultiSelectDeleteActivity.this.getContentResolver().delete(uri, null, null);
                                }
                                delListAdapter.idSet.removeAll(ids);
                                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);
                                }
                                delListAdapter.cursor = result;
                                delListAdapter.notifyDataSetChanged();
                                progressDialog.dismiss();
                            }
                        };
                        progressDialog.show();
                        deleteWork.execute(delListAdapter.idSet);
                    }
                })
                .setCancelable(true)
                .create()
                .show();
            break;
           
         // 取消按鈕
        case R.id.can_btn:
           
            break;
        }
    }
}三、案例效果展示

 

 

\ \ \

\ \ \

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved