先看我实现的效果:
a. b.
c. d.
本来想用spinner实现的,由Android中联系人问题一知道,spinner不是那么好用,主要是不能很好的控制。于是我在这里自己用一个TextView来代替spinner,如图a,用弹出框的地方来加载web中的那么多可选择的联系人,没办法,谁叫手机的可用面积这么小呢。
android实现的功能:
1、选择联系人,一开始会弹出如图b,因为没有数据,所以点击增加,可以弹到c中,选择好数据后保存到弹出列表d中,其中包括可以一次性选择多条联系(如c图)人(web上每次只能选择一条);
2、可以动态删除联系人(如d图),联系人删除后,可选的数据中便会增加删除的联系人数据,也就是为了不造成数据的重复性。
3、可以动态的修改联系人,这个跟web的功能是一样的,当我们点击d中的对话框中的任何一条已经选择好的联系人,都可以跳到c中更换你想要的联系人,当然c中的数据是没有d中数据,和2一样,为了不造成数据的重复性。
难点:
1、数据的正确加载,也就是数据列表或者数组的动态增删;
2、确保数据的唯一性,不造成重复。
因为对话框生成多选列表需要的数据为一个数组,
public Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, final OnMultiChoiceListener listener)
于是我在这里一开始给出一个字符串数组
public static String[] mItems = { "item0", "item1", "itme2", "item3", "itme4", "item5", "item6" };
于是关键的业务就是对这个数组中的数据进行增删操作
对数组删除数据的方法:
private String[] removeIndexOfArray(String[] items,
ArrayList<Integer> indexs) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < items.length; i++) {
list.add(items[i]);
}
Collections.sort(indexs);
for (int i = 0; i < indexs.size(); i++) {
list.remove(indexs.get(i) - i); //备注1
}
Object[] obj = list.toArray();
String[] strs = new String[obj.length];
for (int i = 0; i < obj.length; i++) {
strs[i] = obj[i].toString();
}
return strs;
}
对数组增加数据的方法:
public static String[] addIndexOfArray(String[] items, String str) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < items.length; i++) {
list.add(items[i]);
}
if (!list.contains(str)) {
list.add(0, str);
}
Object[] obj = list.toArray();
String[] strs = new String[obj.length];
for (int i = 0; i < obj.length; i++) {
strs[i] = obj[i].toString();
}
return strs;
}
注释一的解释:这里从数组中删除数据的时候,很容易出现的问题,比如我要从该数组中把第一、第四、第六位置的值(也就是零、三、六)加载到我的联系人列表中,用如下的图示:
甲图是一开始的数据和序列号的对比,我们一开始加载第一个,也就是序列号是0的值,联系人列表加载了该数据,为了保证数据的唯一性,那么数组中的该值就要删掉,于是便有了乙图,可是在数组中的序列发生了变化,零已经被删除了,三到了序列号为2的位置,六到了序列号为5的位置;
加载三,因为三到了序列号2的位置,所以我们需要把前面定义好的序列号减去1,然后加载需要的三;加载后数组的序列号和值重新分配,如图丙。
同理,加载五,需要我们把前面定义好的序列号减去2,然后加载需要的五。
于是可以得到 list.remove(indexs.get(i) - i);注释一处的语句。
看关键代码:
1、首先我们要点击TextView的时候弹出一个对话框:
taskContactsText.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
final AlertDialog.Builder builder = new AlertDialog.Builder(TaskEditOrNew.this);
LayoutInflater factory = LayoutInflater.from(TaskEditOrNew.this);
final View contactsView = factory.inflate(R.layout.task_layout_edit_contact_list, null);
builder.setTitle("Contacts");
builder.setView(contactsView).show();
taskContactsList = (ListView) contactsView.findViewById(R.id.task_id_edit_contact_list);
initContactData();
}
});
2、在该弹出框的基础上,我们需要显示出用来选择的数据,于是initContactData()方法中的代码如下:
private void initContactData() {
taskContactsList.setAdapter(listItemAdapter);
taskContactsList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1,
final int arg2, long arg3) {
// TODO Auto-generated method stub
MultiChoiceID.clear();
AlertDialog.Builder builder = new AlertDialog.Builder(
TaskEditOrNew.this);
builder.setTitle("Contacts");
builder.setMultiChoiceItems(mItems, new boolean[] { false, //备注1
false, false, false, false, false, false },
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog,
int whichButton, boolean isChecked) {
atIndex = whichButton;
if (isChecked) {
MultiChoiceID.add(whichButton);
} else {
MultiChoiceID.remove(whichButton);
}
}
});
).show();
}
});
}
3、确定操作代码:
builder.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
private HashMap<String, Object> map;
public void onClick(DialogInterface dialog,
int whichButton) {
if (arg2 == (taskContactsListData.size() - 1)) {
for (int i = 0; i < MultiChoiceID.size(); i++) {
map = new HashMap<String, Object>();
map.put("name",
mItems[MultiChoiceID.get(i)]);
map.put("delete", R.drawable.delete);
taskContactsListData.add(
taskContactsListData.size() - 1,
map);
}
mItems = removeIndexOfArray(mItems,
MultiChoiceID);
} else {
String key = taskContactsListData.get(arg2)
.get("name").toString();
taskContactsListData.get(arg2).put("name",
mItems[atIndex]);
mItems[atIndex] = key;
}
listItemAdapter.notifyDataSetChanged();
setTaskContactsText();
}
});
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
}
}