先看我实现的效果:
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()方法中的代码如下:
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) { } }