編輯:關於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;
}
}
}三、案例效果展示
應用小掛件(也叫做窗口小掛件)在android1.5的時候被第一次引出,後來再android3.0和android3.1中得到了極大的發展,他們可以展示一些應用的常用信息
今天繼續講解Fragment組件的特性,主要是跟Activity的交互和生命周期的關系,我們前面已經說過Fragment是依賴於Activity的,而且生命周期也跟Act
上一篇文章中我們講解了Android中的幾種常見網絡協議:xml,json,protobuf等,以及各自的優缺點,一般而言主要我們的App涉及到了網絡傳輸都會有這方面的內
以下源碼來自Launcher2.3的例子 1.默認每個應用的主Activity都會自帶 ,表示該應用安裝到Launcher時點擊打開該Activity 2.