編輯:關於Android編程
網上Android聯系人列表的例子也很多,都和微信的聯系人差不多,由於項目用到了聯系人列表索引功能(產品把字母item給去掉了),不過也還是好實現,這裡我也來分享分享我的實現,免得以後忘了,那先看看效果(Demo在結尾有下載地址):
要達到的效果就是這麼簡單。
先說說思路吧:首先為聯系人對象添加一個pinyin字段,當獲取到了聯系人原始數據後,把每個聯系人的名字轉換為拼音,並為pinyin字段設置值。然後獲取聯系人中出現過哪些字母的拼音保存為數組(這就是字母的item),然後和聯系人拼音再組合成新的數組,利用Arrays.sort排序功能,就依次按字母順序拍好了聯系人列表,接下來就是把字母在聯系人列表中出現的位置給保存起來,繪制右邊字母索引時,給相應的字母設置當前字母在聯系人列表的位置,滑動到某一個字母是,就把listview移動到那個位置就行了。
一:先看看提取聯系人中出現的字母,並排序
/** * 把數據排序,並把A-Z順序加進去 * * @param carTypes * @return */ public String[] sortIndex(List這個返回的就是排好序的字母順序了(如[A, 安妮,G,蓋倫...Z])。constastBeans) { TreeSet set = new TreeSet (); for (ConstastBean constastBean : constastBeans) { char ch = constastBean.getPinyin().charAt(0); set.add(String.valueOf(ch).toUpperCase(Locale.getDefault()));// 獲取出現的首字母 } String[] names = new String[constastBeans.size() + set.size()];// 新數組,用於保存首字母 + 聯系人拼音 int i = 0; for (String string : set) { // 把set中的字母添加到新數組中(前面) names[i] = string; i++; } //把聯系人拼音提取到一個數組中 String[] pyheader = new String[constastBeans.size()]; for (int j = 0; j < constastBeans.size(); j++) { pyheader[j] = constastBeans.get(j).getPinyin(); } System.arraycopy(pyheader, 0, names, set.size(), pyheader.length);// 把聯系人拼音添加到後面,結果就是聯系人拼音和出現過的首字母在一個數組裡面(是無序的) // 自動按照首字母排序 Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);// 嚴格按照字母順序排序,忽略字母大小寫,結果為按拼音排序的數組返回 return names; }
二:接下來就是根據返回的順序,把聯系人對象排序
/** * 根據名字排序對數據進行排序 因為默認是數字在首位,為了把數字排到末尾,需要進行轉換 * * @param arry * @return */ public ArrayListgetAllLists(String[] arry) { ArrayList lists = new ArrayList ();// 保存排好序的數據 ArrayList lists2 = new ArrayList ();// 保存數字開頭的數據 ArrayList lists3 = new ArrayList ();// 保存字母數據 // 對數據進行排序 for(int i = 0; i < arry.length; i++) { for(int j = 0; j < sourceData.size(); j++) { if(arry[i].equals(sourceData.get(j).getPinyin())) { lists.add(sourceData.get(j)); break; } // else //需要顯示單個字母的item,這裡就不用注釋,在adapter中應給為這個item單獨設置一個布局 // { // ConstastBean contactBean = new ConstastBean(); // contactBean.setPinyin(arry[i]); // contactBean.setNickName(arry[i]); // lists.add(contactBean); // break; // } } } // 分離出數字數據和字母數據 int index = getLetter(lists);// 獲取字母開頭的位置 for(int i = 0; i < lists.size(); i++) { if(i < index) { lists2.add(lists.get(i)); } else { lists3.add(lists.get(i)); } } lists.clear(); lists.addAll(lists3); lists.addAll(lists2); return lists; }
由於排好序的是數字在字母前面,但是這裡需要數字在後面,所以先查詢第一個字母出現的位置,然後從那個位置截取為2個集合,再把數字集合添加到字母集合後面就行了。
三:初始化工作都做好了,就該遍歷獲取每個字母所對應的位置了
selector = new HashMap(); // 遍歷排好序的數據,獲取每個字母的位置 for (int i = 0; i < indexStr.length; i++) { for (int j = 0; j < datas.size(); j++) { if (datas.get(j).getPinyin().toLowerCase(Locale.getDefault()).startsWith(indexStr[i ].toLowerCase(Locale.getDefault()))) { selector.put(indexStr[i], j); break; } String pinyin = datas.get(j).getPinyin(); if(indexStr[i].equals(#) && isNumeric(pinyin.substring(0,1))) { selector.put(indexStr[i], j); return; } } }
返回的結果就類似於這種:{D=2, #=23, E=4, G=5, A=0, L=11, M=12, N=14, H=6, J=8, K=10, T=19, V=20, S=16, R=15, Z=21}
/** * 繪制索引條 */ public void drawIndexView() { LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, height); for (int i = 0; i < indexStr.length; i++) { TextView tv = new TextView(this); tv.setLayoutParams(params); tv.setText(indexStr[i]); tv.setGravity(Gravity.CENTER); tv.setTextColor(this.getResources().getColor(R.color.indexs_color)); tv.setTextSize(13); layoutIndex.addView(tv); layoutIndex.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub float y = event.getY(); int index = (int) y / height;// 得到點擊字母位置的索引 String key = ; if (index < indexStr.length && index > -1) { key = indexStr[index]; if (selector.containsKey(key)) { int position = selector.get(key); if (listView.getHeaderViewsCount() > 0) {// 添加的header給去掉 listView.setSelectionFromTop( position + listView.getHeaderViewsCount(), 0); } else { listView.setSelectionFromTop(position, 0);// 滑動到第一項 } } if (key.equals(↑)) { listView.setSelectionFromTop(0, 0);// 滑動到第一項 } } if(!key.equals()) { showTv.setText(key); showTv.setVisibility(View.VISIBLE); } switch (event.getAction()) { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_OUTSIDE: showTv.setVisibility(View.GONE); break; case MotionEvent.ACTION_DOWN: // layoutIndex.setBackground(); break; } return true; } }); } }這樣就完成了帶索引的聯系人列表的實現:Demo源碼下載
一.這一篇我們要從網絡為首頁加載數據,解析數據,並為各個組件設置數據。我們先來看看HomePage的代碼,邏輯後面分析。代碼看起雖然挺多的,邏輯卻沒有幾步。public
什麼都先別說,先看預覽圖!預覽圖中是限制了同時最大下載數為 2 的.其實下載管理器的實現是挺簡單的,我們需要弄清楚幾點就行了服務基礎首先我們需要明確一點,下載我們應該使用
這篇博客我們來介紹一下模板方法模式(Template Method Pattern),也是行為型設計模式之一。在面向對象開發過程中,通常會遇到這樣的一個問題,我們知道一個
先看一下效果圖Tinker已知問題由於原理與系統限制,Tinker有以下已知問題: Tinker不支持修改AndroidManifest.xml,Tinker不支持新增