先看我實現的效果:
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 stubfinal 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 stubMultiChoiceID.clear();AlertDialog.Builder builder = new AlertDialog.Builder(TaskEditOrNew.this);builder.setTitle("Contacts");builder.setMultiChoiceItems(mItems, new boolean[] { false,//備忘1false, 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) {}}