歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android之實現系統聯系人軟件的分組和字母提示效果

Android之實現系統聯系人軟件的分組和字母提示效果

日期:2017/3/1 10:41:50   编辑:Linux編程

聯系人分章節顯示以及ListView快速滑動顯示聯系人首字母例子,查閱網上很多這樣的例子後,發現普遍是從系統源碼裡面抽取的,而且普遍比較復雜,這裡做了精簡,擴展性較強,移植起來非常方便。

1.FastContactSearchDemoActivity.java

  1. package com.zhf.FastContactSearchDemo;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Set;
  7. import java.util.regex.Pattern;
  8. import Android.app.Activity;
  9. import android.content.AsyncQueryHandler;
  10. import android.content.ContentResolver;
  11. import android.content.ContentValues;
  12. import android.content.Context;
  13. import android.database.Cursor;
  14. import android.net.Uri;
  15. import android.os.Bundle;
  16. import android.view.LayoutInflater;
  17. import android.view.View;
  18. import android.view.ViewGroup;
  19. import android.widget.BaseAdapter;
  20. import android.widget.ListView;
  21. import android.widget.SectionIndexer;
  22. import android.widget.TextView;
  23. /**
  24. * 聯系人分章節顯示以及ListView快速滑動顯示聯系人首字母例子
  25. * 本例來自http://blog.csdn.net/luck_apple/article/details/6741860
  26. * 查閱網上很多這樣的例子後,發現普遍是從系統源碼裡面抽取的,而且普遍比較復雜,這裡做了精簡,擴展性較強,移植起來非常方便。
  27. * @author [email protected]
  28. *
  29. */
  30. public class FastContactSearchDemoActivity extends Activity {
  31. private BaseAdapter adapter;
  32. private ListView personList;
  33. private AsyncQueryHandler asyncQuery;
  34. private static final String NAME = "name", NUMBER = "number",
  35. SORT_KEY = "sort_key";
  36. @Override
  37. public void onCreate(Bundle savedInstanceState) {
  38. super.onCreate(savedInstanceState);
  39. setContentView(R.layout.main);
  40. personList = (ListView) findViewById(R.id.listView);
  41. asyncQuery = new MyAsyncQueryHandler(getContentResolver());
  42. }
  43. @Override
  44. protected void onResume() {
  45. super.onResume();
  46. Uri uri = Uri.parse("content://com.android.contacts/data/phones"); // 聯系人的Uri
  47. String[] projection = { "_id", "display_name", "data1", "sort_key" }; // 查詢的列
  48. asyncQuery.startQuery(0, null, uri, projection, null, null,
  49. "sort_key COLLATE LOCALIZED asc"); // 按照sort_key升序查詢
  50. }
  51. /**
  52. * 數據庫異步查詢類AsyncQueryHandler
  53. *
  54. * @author administrator
  55. *
  56. */
  57. private class MyAsyncQueryHandler extends AsyncQueryHandler {
  58. public MyAsyncQueryHandler(ContentResolver cr) {
  59. super(cr);
  60. }
  61. /**
  62. * 查詢結束的回調函數
  63. */
  64. @Override
  65. protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
  66. if (cursor != null && cursor.getCount() > 0) {
  67. List<ContentValues> list = new ArrayList<ContentValues>();
  68. cursor.moveToFirst();
  69. for (int i = 0; i < cursor.getCount(); i++) {
  70. ContentValues cv = new ContentValues();
  71. cursor.moveToPosition(i);
  72. String name = cursor.getString(1);
  73. String number = cursor.getString(2);
  74. String sortKey = cursor.getString(3);
  75. if (number.startsWith("+86")) {// 去除多余的中國地區號碼標志,對這個程序沒有影響。
  76. cv.put(NAME, name);
  77. cv.put(NUMBER, number.substring(3));
  78. cv.put(SORT_KEY, sortKey);
  79. } else {
  80. cv.put(NAME, name);
  81. cv.put(NUMBER, number);
  82. cv.put(SORT_KEY, sortKey);
  83. }
  84. list.add(cv);
  85. }
  86. if (list.size() > 0) {
  87. setAdapter(list);
  88. }
  89. }
  90. }
  91. }
  92. private void setAdapter(List<ContentValues> list) {
  93. adapter = new ListAdapter(this, list);
  94. personList.setAdapter(adapter);
  95. }
  96. private static class ViewHolder {
  97. TextView alpha;
  98. TextView name;
  99. TextView number;
  100. }
  101. /**
  102. * 其他項目使用時,只需要傳進來一個有序的list即可
  103. */
  104. private class ListAdapter extends BaseAdapter implements SectionIndexer {
  105. private LayoutInflater inflater;
  106. private List<ContentValues> list;
  107. private HashMap<String, Integer> alphaIndexer;//保存每個索引在list中的位置【#-0,A-4,B-10】
  108. private String[] sections;//每個分組的索引表【A,B,C,F...】
  109. public ListAdapter(Context context, List<ContentValues> list) {
  110. this.inflater = LayoutInflater.from(context);
  111. this.list = list; // 該list是已經排序過的集合,有些項目中的數據必須要自己進行排序。
  112. this.alphaIndexer = new HashMap<String, Integer>();
  113. for (int i =0; i <list.size(); i++) {
  114. String name = getAlpha(list.get(i).getAsString(SORT_KEY));
  115. if(!alphaIndexer.containsKey(name)){//只記錄在list中首次出現的位置
  116. alphaIndexer.put(name, i);
  117. }
  118. }
  119. Set<String> sectionLetters = alphaIndexer.keySet();
  120. ArrayList<String> sectionList = new ArrayList<String>(
  121. sectionLetters);
  122. Collections.sort(sectionList);
  123. sections = new String[sectionList.size()];
  124. sectionList.toArray(sections);
  125. }
  126. @Override
  127. public int getCount() {
  128. return list.size();
  129. }
  130. @Override
  131. public Object getItem(int position) {
  132. return list.get(position);
  133. }
  134. @Override
  135. public long getItemId(int position) {
  136. return position;
  137. }
  138. @Override
  139. public View getView(int position, View convertView, ViewGroup parent) {
  140. ViewHolder holder;
  141. if (convertView == null) {
  142. convertView = inflater.inflate(R.layout.list_item, null);
  143. holder = new ViewHolder();
  144. holder.alpha = (TextView) convertView.findViewById(R.id.alpha);
  145. holder.name = (TextView) convertView.findViewById(R.id.name);
  146. holder.number = (TextView) convertView
  147. .findViewById(R.id.number);
  148. convertView.setTag(holder);
  149. } else {
  150. holder = (ViewHolder) convertView.getTag();
  151. }
  152. ContentValues cv = list.get(position);
  153. String name = cv.getAsString(NAME);
  154. String number = cv.getAsString(NUMBER);
  155. holder.name.setText(name);
  156. holder.number.setText(number);
  157. // 當前聯系人的sortKey
  158. String currentStr = getAlpha(list.get(position).getAsString(
  159. SORT_KEY));
  160. // 上一個聯系人的sortKey
  161. String previewStr = (position - 1) >= 0 ? getAlpha(list.get(
  162. position - 1).getAsString(SORT_KEY)) : " ";
  163. /**
  164. * 判斷顯示#、A-Z的TextView隱藏與可見
  165. */
  166. if (!previewStr.equals(currentStr)) { // 當前聯系人的sortKey!=上一個聯系人的sortKey,說明當前聯系人是新組。
  167. holder.alpha.setVisibility(View.VISIBLE);
  168. holder.alpha.setText(currentStr);
  169. } else {
  170. holder.alpha.setVisibility(View.GONE);
  171. }
  172. return convertView;
  173. }
  174. /*
  175. * 此方法根據聯系人的首字母返回在list中的位置
  176. */
  177. @Override
  178. public int getPositionForSection(int section) {
  179. String later = sections[section];
  180. return alphaIndexer.get(later);
  181. }
  182. /*
  183. * 本例中可以不考慮這個方法
  184. */
  185. @Override
  186. public int getSectionForPosition(int position) {
  187. String key = getAlpha(list.get(position).getAsString(SORT_KEY));
  188. for (int i = 0; i < sections.length; i++) {
  189. if (sections[i].equals(key)) {
  190. return i;
  191. }
  192. }
  193. return 0;
  194. }
  195. @Override
  196. public Object[] getSections() {
  197. return sections;
  198. }
  199. }
  200. /**
  201. * 提取英文的首字母,非英文字母用#代替
  202. *
  203. * @param str
  204. * @return
  205. */
  206. private String getAlpha(String str) {
  207. if (str == null) {
  208. return "#";
  209. }
  210. if (str.trim().length() == 0) {
  211. return "#";
  212. }
  213. char c = str.trim().substring(0, 1).charAt(0);
  214. // 正則表達式,判斷首字母是否是英文字母
  215. Pattern pattern = Pattern.compile("^[A-Za-z]+{1}quot;);
  216. if (pattern.matcher(c + "").matches()) {
  217. return (c + "").toUpperCase(); // 大寫輸出
  218. } else {
  219. return "#";
  220. }
  221. }
  222. }

Copyright © Linux教程網 All Rights Reserved