3.3选择
有2种选择方式,逐条选择和全选。
逐条选择时,会调用onListItemClick方法,MultiPickContactActivity的onListItemClick方法逻辑如下,
1,获取CheckBox的选取状态,
CheckBox checkBox = (CheckBox) v.findViewById(R.id.pick_contact_check);
boolean isChecked = !checkBox.isChecked();
checkBox.setChecked(isChecked);
2,获取ContactItemListAdapter的bindView方法封装的ContactItemCache对象,
String[] value = null;
ContactItemCache cache = (ContactItemCache) v.getTag();
3,根据不同类型,获取ContactItemCache的变量信息并保存在value中,例如,SIM卡的处理如下,
value = new String[] {cache.name, cache.number, cache.email, cache.anrs};
这个处理一定和ContactItemListAdapter的bindView方法是一一对应的。
4,将选择的item通过键值对的方式封装在mChoiceSet中,
mChoiceSet.putStringArray(String.valueOf(id), value);
mChoiceSet 是Bundle对象。
5,当然是已经选中了然后取消的处理如下,
mChoiceSet.remove(String.valueOf(id));
mSelectAllCheckBox.setChecked(false);
MultiPickContactActivity中onClick对全选控件事件的处理如下,
case R.id.select_all_check:
if (mSelectAllCheckBox.isChecked()) {
selectAll(true);
} else {
selectAll(false);
}
break;
selectAll方法逻辑如下,
1,对查询结果的数据库进行逐个处理,
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
String id = null;
String[] value = null;
2,逐条处理时,根据不同类型分别进行处理,例如,对SIM卡联系人处理如下,
首先查询SIM卡联系人对应的信息,
id = String.valueOf(cursor.getLong(SIM_COLUMN_ID));
String name = cursor.getString(SIM_COLUMN_DISPLAY_NAME);
String number = cursor.getString(SIM_COLUMN_NUMBER);
String email = cursor.getString(SIM_COLUMN_EMAILS);
String anrs = cursor.getString(SIM_COLUMN_ANRS);
然后将这些信息封装在value中,
value = new String[] {name, number, email, anrs, id};
其实,这个过程和ContactItemListAdapter的bindView方法以及单选的细节完全相同,因此,完全可以在ContactItemListAdapter的bindView方法中,将这些信息保存在全局变量中,在selectAll方法直接拿出来就可以。这样代码更简洁,效率更高。
3,在逐条处理中,还是打包到mChoiceSet中,
if (isSelected) {
mChoiceSet.putStringArray(id, value);
} else {
mChoiceSet.remove(id);
}
mChoiceSet是一个Bundle对象,定义如下,
private Bundle mChoiceSet;
因此,经过选择过程,将所有需要处理的信息都保存在mChoiceSet中。
3.4执行
选好之后,点击确认按钮就开始执行, MultiPickContactActivity中onClick对确定控件事件的处理逻辑如下,
1,如果是搜索模式,就退出,
if (isSearchMode()) {
exitSearchMode(true);
}
2,分别对5种不同类型进行处理,例如,对SIM卡的处理如下,
if (mChoiceSet.size() > 0) {
showDialog(R.id.dialog_import_sim_contact_confirmation);
}
MultiPickContactActivity的onCreateDialog方法中会加载3种dialog,分别是,删除联系人,删除通话记录,导入导出联系人, 导入导出联系人处理如下,
return new AlertDialog.Builder(this).setTitle(R.string.importConfirmation_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.ContactMultiImportConfirmation)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DeleteClickListener()).create();
DeleteClickListener也是MultiPickContactActivity的内部类,
private class DeleteClickListener implements DialogInterface.OnClickListener {
其onClick逻辑如下,
1,根据是否是和SIM卡有关,分别构造ImportAllSimContactsThread 和 DeleteContactsThread线程,
if (isPickSim()) {
thread = new ImportAllSimContactsThread();
} else {
thread = new DeleteContactsThread();
}
2,启动子线程执行任务,
thread.start();
因为,这些都是耗时操作,可能长达几十秒钟,所以需要另外开启线程去执行。
ImportAllSimContactsThread的run方法逻辑如下,
1,获取变量,
mTotalCount = mChoiceSet.size(); // 获取选中的SIM卡联系人条数
ArrayList<ContentProviderOperation> operationList =
new ArrayList<ContentProviderOperation>();
2,逐条处理,逐条操作逻辑如下,
如果在遍历的同时,点击了取消,则调用doApplyBatch方法将当前已处理的SIM卡联系人导入,
if (mCanceled) {
if (operationList.size() > 0) {
doApplyBatch(operationList, resolver);
}
break;
}
调用buildSimContentProviderOperationList方法进行插入语句的封装,封装为ContentProviderOperation,
String[] values = mChoiceSet.getStringArray(key);
int firstBatch = operationList.size();
buildSimContentProviderOperationList(values, resolver, mAccount, firstBatch,
operationList, mPhoneNumberSet);
3,封装完成之后,调用doApplyBatch方法插入数据库,
if (operationList.size() > 0) {
doApplyBatch(operationList, resolver);
}
4,最后调用finish方法,
finish();