zoukankan      html  css  js  c++  java
  • Android带索引联系人列表

    网上Android联系人列表的样例也非常多,都和微信的联系人差点儿相同,因为项目用到了联系人列表索引功能(产品把字母item给去掉了),只是也还是好实现。这里我也来分享分享我的实现,免得以后忘了。那先看看效果(Demo在结尾有下载地址):


    要达到的效果就是这么简单。

    先说说思路吧:首先为联系人对象加入一个pinyin字段,当获取到了联系人原始数据后,把每一个联系人的名字转换为拼音。并为pinyin字段设置值。

    然后获取联系人中出现过哪些字母的拼音保存为数组(这就是字母的item),然后和联系人拼音再组合成新的数组,利用Arrays.sort排序功能,就依次按字母顺序拍好了联系人列表,接下来就是把字母在联系人列表中出现的位置给保存起来,绘制右边字母索引时,给对应的字母设置当前字母在联系人列表的位置,滑动到某一个字母是,就把listview移动到那个位置即可了。


    一:先看看提取联系人中出现的字母,并排序

    /**
    	 * 把数据排序。并把A-Z顺序加进去
    	 * 
    	 * @param carTypes
    	 * @return
    	 */
    	public String[] sortIndex(List<ConstastBean> constastBeans) {
    		TreeSet<String> set = new TreeSet<String>();
    		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++;
    		}
    <span style="white-space:pre">		</span>//把联系人拼音提取到一个数组中
    		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);// <span style="font-family: Arial, Helvetica, sans-serif;">把联系人拼音加入到后面,结果就是联系人拼音和出现过的首字母在一个数组里面(是无序的)</span>
    
    		// 自己主动依照首字母排序
    		Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);// 严格依照字母顺序排序,忽略字母大写和小写,结果为按拼音排序的数组返回
    		return names;
    
    	}
    这个返回的就是排好序的字母顺序了(如[A, 安妮,G,盖伦...Z])。

    二:接下来就是依据返回的顺序,把联系人对象排序

    /**
    	 * 依据名字排序对数据进行排序 由于默认是数字在首位,为了把数字排到末尾,须要进行转换
    	 * 
    	 * @param arry
    	 * @return
    	 */
    	public ArrayList<ConstastBean> getAllLists(String[] arry)
    	{
    		ArrayList<ConstastBean> lists = new ArrayList<ConstastBean>();// 保存排好序的数据
    		ArrayList<ConstastBean> lists2 = new ArrayList<ConstastBean>();// 保存数字开头的数据
    		ArrayList<ConstastBean> lists3 = new ArrayList<ConstastBean>();// 保存字母数据
    		// 对数据进行排序
    		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个集合。再把数字集合加入到字母集合后面即可了。

    三:初始化工作都做好了。就该遍历获取每一个字母所相应的位置了

    <span style="white-space:pre">	</span>selector = new HashMap<String, Integer>();
    	// 遍历排好序的数据,获取每一个字母的位置
    	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<span style="white-space:pre">			</span>].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源代码下载







  • 相关阅读:
    将数据库dbcp连接池改为c3p0连接池(草稿,别点)
    java遍历set集合
    mybatis映射文件(转)
    java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
    redis通过json方案存取对象com.alibaba.fastjson.JSONException: syntax error, expect
    PL/SQL配置oracle客户端,登录远程数据库配置
    Weblogic部署项目三种方式
    Service具体解释(二):Service生命周期
    Coredata — 入门使用
    UML建模学习1:UML统一建模语言简单介绍
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6979908.html
Copyright © 2011-2022 走看看