android字母索引流程:

界面步骤:
  1、初始化右侧字母的高度以及大小
  2、回执索引列表,并为列表当中的字母设置监听事件

业务逻辑步骤:
   1、先从服务器读取我的好友列表
   2、将好友的名字转换为拼音,并取得首字母,按照字母大小进行排序。装载联系人非字母为首的数组。保存到selector HashMap当中。键为联系人的字母的开头,值为联系人在这个集合里面的下标
   3、取得返回数据装载到适配器里面去

会用到的第三方库:pinyin4j.jar :http://download.csdn.net/detail/q908555281/9296197

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><!-- 这个用来显示联系人的列表 --><ListViewandroid:id="@+id/listview_news_friends"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/comment_background"android:cacheColorHint="#00000000"android:divider="@null"android:fadingEdge="none"android:scrollbars="none" ></ListView><!-- 这个用来显示右侧字母栏的布局 --><LinearLayoutandroid:id="@+id/lilayout_news_friends"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="right"android:background="#d7d7d7"android:gravity="center"android:orientation="vertical" ></LinearLayout><!-- 这个用来显示点击字母后,屏幕中间出现的字母提示 --><TextViewandroid:id="@+id/tv_news_friends_letter"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:background="@color/white"android:gravity="center"android:paddingBottom="@dimen/px_20"android:paddingLeft="@dimen/px_30"android:paddingRight="@dimen/px_30"android:paddingTop="@dimen/px_20"android:text="A"android:textColor="@color/common_text_input"android:textSize="@dimen/text_size_25"android:visibility="gone" /></FrameLayout>

主类:


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.slife.gopapa.R;
import com.slife.gopapa.activity.news.ContactsActivity;
import com.slife.gopapa.adapter.FriendsAdapter;
import com.slife.gopapa.application.MyApplication;
import com.slife.gopapa.common.APPConstants;
import com.slife.gopapa.dao.JArrayErrorDao;
import com.slife.gopapa.dao.impl.JArrayErrorDaoImpl;
import com.slife.gopapa.database.DBConstants;
import com.slife.gopapa.http.MyHttpClient;
import com.slife.gopapa.model.ContactsPerson;
import com.slife.gopapa.util.ChineseTransferUtils;/**
* @ClassName: FriendsFragment
* @Description: 我的好友界面
*  界面步骤:
*  1、初始化右侧字母的高度以及大小
*  2、回执索引列表,并为列表当中的字母设置监听事件
*
*   业务逻辑步骤:
*   1、先从服务器读取我的好友列表
*   2、将好友的名字转换为拼音,并取得首字母,按照字母大小进行排序。装载联系人非字母为首的数组。保存到selector HashMap当中。键为联系人的字母的开头,值为联系人在这个集合里面的下标
*
*   3、取得返回数据装载到适配器里面去
* @author 菲尔普斯
* @date 2015-3-26 下午5:12:37
**/
public class FriendsFragment extends Fragment {@ViewInject(R.id.listview_news_friends)private ListView listView; // 联系人列表@ViewInject(R.id.tv_news_friends_letter)private TextView txCenter; // 显示在中间的字母@ViewInject(R.id.lilayout_news_friends)private LinearLayout layoutIndex;private HashMap<String, Integer> selector = new HashMap<String, Integer>();// 存放含有索引字母的位置private static final String[] indexStr = { "☆", "A", "B", "C", "D", "E","F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R","S", "T", "U", "V", "W", "X", "Y", "Z", "#" };// 右边的字母private List<ContactsPerson> newPersons = new ArrayList<ContactsPerson>();// 对联系人进行转换成拼音private int height;// 字体高度private boolean flag = false;// 选中标签private FriendsAdapter adapter;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_friends, container,false);ViewUtils.inject(this, view);View headView = inflater.inflate(R.layout.view_friends_headview, null);listView.addHeaderView(headView);initOverload();initListView();return view;}private void initListView() {adapter = new FriendsAdapter(getActivity(), newPersons);listView.setAdapter(adapter);new GetFriendListTask().execute();listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {if(position==0){startActivity(new Intent(getActivity(),ContactsActivity.class));}}});}/*** @Title: initOverload* @Description: 初始化右侧字母栏高度* @param* @return void* @throws*/private void initOverload() {// 这是获取屏幕宽高的监听器ViewTreeObserver observer = layoutIndex.getViewTreeObserver();observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {public boolean onPreDraw() {if (!flag) {// 获取每个字母的高度height = layoutIndex.getMeasuredHeight() / indexStr.length;getIndexView();flag = true;}return true;}});}/*** @Title: getIndexView* @Description: 绘制索引列表(字母列表的监听事件)* @param* @return void* @throws*/public void getIndexView() {LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, height);for (int i = 0; i < indexStr.length; i++) {final TextView tv = new TextView(this.getActivity());// 右侧字母索引tv.setLayoutParams(params);tv.setText(indexStr[i]);// 右侧字母tv.setPadding(10, 0, 10, 0);tv.setTextSize(12);tv.setTextColor(Color.parseColor("#3E75A9"));layoutIndex.addView(tv);// 设置右侧索引布局的触摸监听器layoutIndex.setOnTouchListener(new OnTouchListener() {@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouch(View v, MotionEvent event) {float y = event.getY();int index = (int) (y / height);if (index > -1 && index < indexStr.length) {// 防止越界String key = indexStr[index];if (selector.containsKey(key)) {int pos = selector.get(key);// 将ListView的item移动到点击相应字母if (listView.getHeaderViewsCount() > 0) {// 防止ListView有标题栏,本例中没有。listView.setSelectionFromTop(pos + listView.getHeaderViewsCount(), 0);} else {listView.setSelectionFromTop(pos, 0);// 滑动到第一项}txCenter.setVisibility(View.VISIBLE);txCenter.setText(indexStr[index]);} else {txCenter.setVisibility(View.VISIBLE);txCenter.setText(indexStr[index]);}}switch (event.getAction()) {case MotionEvent.ACTION_DOWN:layoutIndex.setBackgroundColor(Color.parseColor("#606060"));txCenter.setVisibility(View.VISIBLE);break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:layoutIndex.setBackgroundColor(Color.parseColor("#00ffffff"));txCenter.setVisibility(View.GONE);break;}return true;}});}}/*** @ClassName: GetFriendListTask * @Description: 取得我的好友列表* @author 菲尔普斯* @date 2015-3-26 下午5:13:45 **/class GetFriendListTask extends AsyncTask<Void, Void, String[]> {@Overrideprotected String[] doInBackground(Void... params) {return MyHttpClient.postDataToService(getActivity(),APPConstants.URL_HOSTNAME+ APPConstants.URL_FRIENDS_LISTSAPP2,MyApplication.tokenApp2, new String[] { "user_account" },new String[] { MyApplication.preferences.getString(DBConstants.USER_ACCOUNT, "") }, null,null);}@Overrideprotected void onPostExecute(String[] result) {super.onPostExecute(result);JArrayErrorDaoImpl.resolveJson(getActivity(), result,new JArrayErrorDao() {@Overridepublic void disposeJsonArray(JSONArray array) {if (array != null && array.length() > 0) {for (int i = 0; i < array.length(); i++) {try {JSONObject obj = array.getJSONObject(i);ContactsPerson info = new ContactsPerson();info.setUser_account(obj.optString("friend_user_account"));info.setExtend_user_account(obj.optString("friend_extend_user_account"));info.setUser_nickname(obj.optString("user_nickname"));info.setUser_logo(obj.getString("user_logo_200"));info.setName(obj.optString("user_nickname"));newPersons.add(info);} catch (JSONException e) {e.printStackTrace();}}layoutIndex.setBackgroundColor(Color.parseColor("#00ffffff"));// 设置背景颜色txCenter.setVisibility(View.GONE); initPinyin();}}@Overridepublic void disponseJsonArrayFinish() {// TODO Auto-generated method stub}});}}/*** @Title: getPinyin* @Description: 获取每个人的拼音的首字母,并setPinyinName为这个首字母。然后将集合进行排序。再将集合里面的每个首字母和Position的位置存放到selector对象当中* @param * @return void* @throws*/@SuppressLint("DefaultLocale")private void initPinyin(){for(int i=0;i<newPersons.size();i++){String name=newPersons.get(i).getUser_nickname();if(name!=null&&!"".equals(name)){String pinyin=ChineseTransferUtils.getPingYin(name);newPersons.get(i).setPinyinName((pinyin.substring(0, 1)).toUpperCase());}}Collections.sort(newPersons); //对联系人进行排序从A-Z(根据pinyinName)for(int j=0;j<indexStr.length;j++){for(int i=0;i<newPersons.size();i++){if(newPersons.get(i).getPinyinName().equals(indexStr[j])){if(!selector.containsKey(indexStr[j])){selector.put(indexStr[j], i);  }}else{if(!selector.containsKey("#")){selector.put("#", i); }}}}adapter.notifyDataSetChanged();}
}

字母处理工具类:


import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;import com.slife.gopapa.model.ContactsPerson;import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;/***** @ClassName: ChineseTransferUtils* @Description: 汉字与拼音以及首字母转换的助手类(pingyin4j的处理)* @author 菲尔普斯* @date 2015-2-2 上午9:59:21* */
public class ChineseTransferUtils {/*** @Title: getPingYin* @Description: 得到 汉字的全部拼音* @param @param src 要转换的对象* @param @return* @return String* @throws*/public static String getPingYin(String src) {char[] stringCharArray = null;stringCharArray = src.toCharArray();String[] stringArray = new String[stringCharArray.length];HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();// 设置输出格式outputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);outputFormat.setVCharType(HanyuPinyinVCharType.WITH_V);String preString = "";int t0 = stringCharArray.length;try {for (int i = 0; i < t0; i++) {// 判断是否为汉字字符if (java.lang.Character.toString(stringCharArray[i]).matches("[\\u4E00-\\u9FA5]+")) {stringArray = PinyinHelper.toHanyuPinyinStringArray(stringCharArray[i], outputFormat);preString += stringArray[0];} else {preString += java.lang.Character.toString(stringCharArray[i]);}}return preString;} catch (BadHanyuPinyinOutputFormatCombination e1) {e1.printStackTrace();}return preString;}/*** @Title: getHeadChar* @Description: 得到首字母* @param @param str* @param @return* @return String* @throws*/public static String getHeadChar(String str) {String convert = "";char word = str.charAt(0);String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);if (pinyinArray != null) {convert += pinyinArray[0].charAt(0);} else {convert += word;}return convert.toUpperCase();}/*** @Title: getPinYinHeadChar* @Description: 得到中文首字母缩写* @param @param str* @param @return* @return String* @throws*/public static String getPinYinHeadChar(String str) {String convert = "";for (int j = 0; j < str.length(); j++) {char word = str.charAt(j);String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);if (pinyinArray != null) {convert += pinyinArray[0].charAt(0);} else {convert += word;}}return convert.toUpperCase();}/*** @Title: sortIndex* @Description: 字母排序。获取排序后的新数据* @param @param persons* @param @return* @return String[]* @throws*/public static String[] sortIndex(List<ContactsPerson> contacts) {TreeSet<String> set = new TreeSet<String>();String a = null;// 获取初始化数据源中的首字母,添加到set中for (ContactsPerson person : contacts) {String pre = ChineseTransferUtils.getPinYinHeadChar(person.getName()).substring(0, 1);if (65 <= pre.charAt(0) && pre.charAt(0) <= 90 || 97 <= pre.charAt(0) && pre.charAt(0) <= 122) {set.add(pre);} else {set.add("!");}}// 新数组的长度为原数据加上set的大小(set内部已经按字母大小排序,将set里的数据装载到数组中以便往后调用系统拷贝方法)String[] names = new String[contacts.size() + set.size()];int i = 0;for (String string : set) {names[i] = string;i++;}String[] pinYinNames = new String[contacts.size()];for (int j = 0; j < contacts.size(); j++) {contacts.get(j).setPinyinName(a = ChineseTransferUtils.getPingYin(contacts.get(j).getName().toString()));pinYinNames[j] = a + "&^-@";}// 将原数据拷贝到新数据中(将pinYinNames数组中的元素从0下标开始复制元素到names数组)// src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置;// length:复制的长度。 注意:src and dest都必须是同类型或者可以进行转换类型的数组.System.arraycopy(pinYinNames, 0, names, set.size(), pinYinNames.length);// 复制后自动按照首字母排序Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);// 这个方法得到的数组不是以A为开头的,所以下面的方法就是重新排布用户名的顺序/**************** 重新排布用户名的顺序开始 ************************/String[] newNames = new String[names.length + 1];// 装载以A为首的数组String[] postNames = new String[names.length];// 装载非字母为首的数组int k = 0;int postCount = 0;int temp = 0;for (String pre : names) {if (65 <= pre.charAt(0) && pre.charAt(0) <= 90 || 97 <= pre.charAt(0) && pre.charAt(0) <= 122) {// 字母开头的数组newNames[k] = names[temp];k++;temp++;} else {// 非字母开头的数组postNames[postCount] = names[postCount];temp = ++postCount;}}// 将非字母开头的数组加到字母开头数组的后面for (int j = 0; j < postCount; j++, k++) {newNames[k] = postNames[j];}temp = 0;// 防止数组中有nullfor (String pew : newNames) {if (pew != null)postNames[temp++] = pew;}/**************** 重新排布用户名的顺序结束 ************************/return postNames;}
}

最后的实体类:因为实体类需要进行排序,所以重写compareTo方法


import java.io.Serializable;/*** @ClassName: ContactsPerson* @Description: 我的好友实体类和通讯录实体类公用 通讯录联系人的实体类 ,以及好友请求列表的实体类* *               status 联系人状态 -2 : 不是手机号 -1 : 是手机但是没有注册啪啪,可邀请 0 :*               是手机且已经注册啪啪,不可添加为好友 1 : 是手机且已经注册啪啪,可添加为好友 2 : 是手机且已经注册啪啪,已经是好友* @author 菲尔普斯* @date 2015-1-4 下午2:15:48* */
public class ContactsPerson implements Serializable,Comparable<ContactsPerson> {/*** @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么)*/private static final long serialVersionUID = -8839670785761661380L;public String name;// 中文名public String pinyinName;// 拼音的名字public String phone; // 电话号码public String status;// 是不是好友(状态,默认-1,代表是还未处理)public String user_account; // 啪啪号public String extend_user_account; // 聊天账号public String user_nickname; // 用户昵称public String user_logo; // 用户头像public ContactsPerson() {super();}public ContactsPerson(String name) {super();this.name = name;}public ContactsPerson(String name, String pinyinName) {super();this.name = name;this.pinyinName = pinyinName;}public ContactsPerson(String name, String pinyinName, String phone) {super();this.name = name;this.pinyinName = pinyinName;this.phone = phone;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPinyinName() {return pinyinName;}public void setPinyinName(String pinyinName) {this.pinyinName = pinyinName;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public String getUser_account() {return user_account;}public void setUser_account(String user_account) {this.user_account = user_account;}public String getExtend_user_account() {return extend_user_account;}public void setExtend_user_account(String extend_user_account) {this.extend_user_account = extend_user_account;}public String getUser_nickname() {return user_nickname;}public void setUser_nickname(String user_nickname) {this.user_nickname = user_nickname;}public String getUser_logo() {return user_logo;}public void setUser_logo(String user_logo) {this.user_logo = user_logo;}@Overridepublic int compareTo(ContactsPerson another) {char a=this.getPinyinName().charAt(0);char b=another.getPinyinName().charAt(0);if(Integer.valueOf(a)>Integer.valueOf(b)){return 1;}else{return -1;}}}

Android 仿美团大众字母索引实现相关推荐

  1. [Android精品源码] Android 仿美团网,探索ListView的A-Z字母排序功能实现选择城市

    Material Design中文版Code4APPPHP100UI4APP 开启辅助访问设为首页收藏本站快捷导航切换到宽版切换风格 石刚 | |我的 |签到打卡 |设置 |消息 |提醒(2) |退出 ...

  2. Android仿微信实现快速索引选择联系人

    Android仿微信实现快速索引选择联系人 原创 2016年03月05日 13:19:20 1640 3 1 一.概述 先看效果图,然后在给大家慢慢介绍  二.实现 先给大家说说这些城市的数据是怎么来 ...

  3. android 美团下拉菜单,Android仿美团分类下拉菜单实例代码

    本文实例为大家分享了Android仿美团下拉菜单的实现代码,分类进行选择,供大家参考,具体内容如下 效果图 操作平台 AS2.0 第三方框架:butterknife build.gradle depe ...

  4. Android 仿美团网,探索使用ViewPager+GridView实现左右滑动查看更多分类的功能

    不记得什么时候,我留意到到美团网首页有使用ViewPager+GridView实现左右滑动查看更多分类的一个功能,感觉它很有趣,于是想着自己动手也实现这样一个功能,和往常一样,主要是想总结一下我在学习 ...

  5. Android 仿美团选择城市、微信通讯录、饿了么点餐列表的导航悬停分组索引列表

    SuspensionIndexBar 项目地址:mcxtzhang/SuspensionIndexBar 简介:快速实现分组悬停.右侧索引导航联动 列表. 如 美团选择城市界面,微信通讯录界面.饿了么 ...

  6. android仿美团评论

    1.仿美团评论布局,效果图,其中引用了 compile 'com.github.ome450901:SimpleRatingBar:1.3.5' 2.listview_pingjia_item.xml ...

  7. 浅谈android中手机联系人字母索引表的实现

    实际上字母索引表的效果,可以说在现在的众多APP中使用的非常流行,比如支付宝,微信中的联系人,还有购物,买票的APP中选择全国城市,切换城市的时候,这时候的城市也就是按照一个字母索引的顺序来显示,看起 ...

  8. android仿美团论文,毕业设计(论文)-基于Android的仿美团系统.docx

    全套设计加扣 3012250582 PAGE \* MERGEFORMAT- 1 - 全套设计加扣 3012250582 湖南软件职业学院 毕业设计 毕业选题 : 基于Android的仿美团系统 指导 ...

  9. Android仿美团外卖点菜联动列表

    Android高仿美团外卖点菜联动列表效果 最近项目中有一个添加购物车的需求,需要做成美团外卖点菜联动ListView的效果,可能有的朋友觉得这很简单,不就是2个Listview点击事件联动处理机制吗 ...

最新文章

  1. 这6种最常见分布式事务解决方案!请拿走不谢!
  2. 图解动软代码生成器使用
  3. JAVA工程师面试题库
  4. Java实现返回的数据为树形结构
  5. 【Linux】一步一步学Linux——make命令(259)
  6. 黄聪: Bootstrap之Form表单验证神器: BootstrapValidator(转)
  7. behavior php,behavior.php
  8. java中GET方式提交和POST方式提交
  9. 顺序表输入栈元素c语言,C语言数据结构之栈简单操作
  10. [转]ssh常用用法小结
  11. iOS 翻译-UIWebView的基本简介-官方文档翻译
  12. MySQL入门之索引
  13. 9.3 LSMW程序创建操作手册 第5 6 7步
  14. g++ linux 编译开栈_linux下使用g++编译cpp工程
  15. Pro*C/C++简单介绍
  16. 开发了个 Flipper 调试工具的 Flutter 版本 SDK,让 Flutter 应用调试起来更容易 1
  17. 升级到AppCompat v22.1.0,现在获得IllegalArgumentException:AppCompat不支持当前的主题功能
  18. 如何放大缩小地图 和 移动拖动 地图 (一张的那种,厂区地图非世界地图)
  19. 你要知道的内存条知识
  20. TTL转RS232电路--分享原理图和参考资料

热门文章

  1. 读格林斯潘回忆录-9
  2. Android开源项目 资源 学习
  3. html中文档流概念+高度塌陷+bfc+浮动清除
  4. 微信小程序一定高度文字的展开与收起
  5. JAVA核心技术,卷1
  6. Android 开发技术干货
  7. 建水实验中学2021高考考成绩查询,高三第一次省统测成绩发布 建水实验中学低进高出、强势崛起...
  8. 上海python招聘微信群_如何用20行Python代码打造一个微信群聊助手?
  9. js数组常用方法(19种)|你会的到底有多少呢?
  10. 【思路】2021美国大学生数学建模竞赛(美赛)思路+参考文献获取/【2021美国大学生数学建模】