android通讯录开发(粗糙实现微信通讯录的功能)

主要实现功能:

一、实现名单的中英文混合排序,按照联系人名单的首字母进行分类。

二、实现右侧的字母导航功能,根据字母定位相应的名单组,方便查找。

三、实现搜索功能(1)输入字母进行搜索时,按照精确查找(如查找张  输入z ;查找张三  输入zs)。

(2)输入汉字进行搜索时,按照相对模糊的查找(如输入“张”,即查找所有包含“张”字的名单,输入“张三”,即查找所有包含“张三”的名单)。

(3)输入其他字符串查找时,只根据第一个字符进行查询。


程序功能效果如下






代码结构:

MainActivity.java 主界面      MyAdapter.java重写一个adapter     Sort.java处理数据的类      

 

activity_main.xml 主界面

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >


    <ListView
        android:id="@+id/listView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_gravity="center_vertical|right"
        android:scaleType="center"
        android:src="@drawable/contact_list_scroll_normal" />

</FrameLayout>


icon.xml当点击导航时,显示在屏幕中间的提示图标

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/bg_hitchar"
    android:gravity="center"
    android:maxWidth="100dp"
    android:minWidth="100dp"
    android:padding="10dp"
    android:textColor="#ffffffff"
    android:textSize="70sp"
    android:visibility="invisible" />



list_item_tag.xml名单组的标题,即对应的首字母

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#555555"
    android:paddingLeft="10dip">

    <TextView
        android:id="@+id/group_list_item_text"
        android:layout_width="wrap_content"
        android:layout_height="20dip"
        android:gravity="center_vertical"
        android:textColor="#ffffff" />

</LinearLayout>



list_item.xml名单item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/list_addfriend_icon" />

    <TextView
        android:id="@+id/group_list_item_text"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center_vertical"
        android:paddingLeft="5dip" />

</LinearLayout>

search.xml搜索框

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchText"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="@string/search_text" />


代码实现:


在初始化、设置监听、在主界面添加icon、把search添加进ListView之后,首先,调用Sort中的autoSort(String[])方法,对数据进行排序,然后使用排序后的String[]创建两个ArrayList,第一个ArrayList(newDataArrayList)调用Sort.addChar(String [])方法添加分组的字母,使用于ListView中。第二个ArrayList(checkArrayList)单纯的把排序后的String[]转换成ArrayList用于数据的搜索。 接着使用newDataArrayList创建MyAdapter对象,MyAdapter根据重写的getView方法生成ListView。当点击导航图片时,根据用户点击的位置判断出用户想要点击的字母,然后查找这个字母在newDataArrayList(即MyAda中的mObject)中的位置,使用ListView.setSelectionFromTop()方法把对应的分组字母显示在最上面。使用搜索功能时,判断输入字符串的是字母还是汉字,如果这个字符串都是字母,则每个字母匹配一次,不成功则从checkArrayList中remove掉。如果输入的全部为汉字,则使用String.contains()判断联系人名单包不包含搜索的字符,不包含则remove。在操作完成后的checkArrayList即为搜索到数据,然后通过MyAdapter用ListView现实出来

   

一、MainActivity.java

package com.example.tongxunlu;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnTouchListener,
		OnGestureListener
{

	private String searchStr = null;

	private Sort mSort = null;

	private Context mContext = null;

	private TextView mIcon = null;

	private MyAdapter mAdapter = null;

	private ListView mListView = null;

	private EditText mSearchText = null;

	private ImageView mImageView = null;

	private GestureDetector mGesture = null;

	private ArrayList<String> newDataArrayList;

	private ArrayList<String> checkArrayList;

	private String[] newData;

	private String[] english = {"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 String[] oldData = {"一败如水", "胆小如鼠", "引狼入室", "风驰电掣", "刀山火海", "一贫如洗",
			"料事如神", "视死如归", "对答如流", "挥金如土", "铁证如山", "度日如年", "心急如焚", "巧舌如簧",
			"如雷贯耳", "如履薄冰", "如日中天", "势如破竹", "稳如泰山", "骨瘦如柴", "爱财如命", "暴跳如雷",
			"门庭若市", "恩重如山", "从善如流", "观者如云", "浩如烟海", "弃暗投明", "取长补短", "厚今薄古",
			"同甘共苦", "因小失大", "优胜劣败", "自生自灭", "评头论足", "远交近攻", "求同存异", "well",
			"hello", "one", "goodtime", "running", "java", "android", "jsp",
			"html", "struts", "Charles", "Mark", "Bill", "Vincent", "William",
			"Joseph", "James", "Henry", "Gary", "Martin"};

	@Override
	/**
	 * 初始化、添加icon、search等view,设置监听
	 */
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mContext = MainActivity.this;

		mImageView = (ImageView) this.findViewById(R.id.imageView1);

		mListView = (ListView) this.findViewById(R.id.listView1);

		mSearchText = (EditText) this.getLayoutInflater().inflate(
				R.layout.search, null);

		mIcon = (TextView) this.getLayoutInflater()
				.inflate(R.layout.icon, null);

		mGesture = new GestureDetector(this);

		getWindowManager()
				.addView(
						mIcon,
						new WindowManager.LayoutParams(
								LayoutParams.WRAP_CONTENT,
								LayoutParams.WRAP_CONTENT,
								WindowManager.LayoutParams.TYPE_APPLICATION,
								WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
										| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
								PixelFormat.TRANSLUCENT));

		mSort = new Sort();

		checkArrayList = new ArrayList<String>();
		
		//得到排序后的数据(String[])
		newData = mSort.autoSort(oldData);

		newDataArrayList = mSort.addChar(newData);//

		mListView.addHeaderView(mSearchText);

		mAdapter = new MyAdapter(this, android.R.layout.simple_list_item_1,
				newDataArrayList);

		mListView.setAdapter(mAdapter);

		mListView.setOnTouchListener(new OnTouchListener()
		{
			
			@Override
			public boolean onTouch(View v, MotionEvent event)
			{
				// TODO Auto-generated method stub
				if(mSearchText.hasFocus())
					mSearchText.clearFocus();
				return false;
			}
		});
		//搜索框监听
		mSearchText.addTextChangedListener(new MyWatchToSearch());

		mImageView.setOnTouchListener(this);

		mImageView.setLongClickable(true);

	}

	class MyWatchToSearch implements TextWatcher
	{

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after)
		{
			// TODO Auto-generated method stub

		}

		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count)
		{
			// TODO Auto-generated method stub
			//搜索功能只针对ListView中的内容数据,不针对标题数据。
			//使用没添加的分组字母的数据创建新的ArrayList
			checkArrayList = mSort.toArrayList(newData);
			searchStr = mSearchText.getText().toString();

			if (searchStr.length() != 0)
			{
				checkSearchStr(searchStr);
				mAdapter = new MyAdapter(mContext,
						android.R.layout.simple_list_item_1, checkArrayList);
				mListView.setAdapter(mAdapter);
			}
		}

		@Override
		public void afterTextChanged(Editable s)
		{
			// TODO Auto-generated method stub
			if (searchStr.length() == 0)
			{
				mAdapter = new MyAdapter(mContext,
						android.R.layout.simple_list_item_1, newDataArrayList);
				mListView.setAdapter(mAdapter);
			}
			mSearchText.requestFocus();
		}

		/**
		 * 
		 */
		public void checkSearchStr(String search)
		{

			String tempSearch;
			String tempList;
			String newDataChar = null;
			String checkArrayListItem = null;
			//当输入的搜索字符为字母时
			if (search.matches("[a-zA-Z]+"))
			{
				for (int i = 0; i < search.length(); i++)
				{
					for (int j = 0; j < checkArrayList.size(); j++)
					{
						checkArrayListItem = checkArrayList.get(j);
						//如果联系人名称不为字母,则得到联系人名称的所有首字母
						if (!checkArrayListItem.matches("[a-zA-Z]+"))
						{
							newDataChar = mSort
									.getAllPinYinHeadChar(checkArrayListItem);
						}
						else
						{
							newDataChar = checkArrayListItem;
						}
						//取出输入的字符串的第i个字母,并转换为大写
						tempSearch = String.valueOf(search.charAt(i))
								.toUpperCase();
						//取出得到的联系人名称所有首字母的第i个字母,并转换为大写
						tempList = String.valueOf(newDataChar.charAt(i))
								.toUpperCase();

						if (!(tempSearch.equals(tempList)))
						{
							checkArrayList.remove(j);
							newDataChar = null;
							j--;
						}
					}
				}
			}
			//当输入的搜索字符为汉字时
			else if (search.matches("[\u4e00-\u9fa5]+"))
			{

				for (int j = 0; j < checkArrayList.size(); j++)
				{
					if (!checkArrayList.get(j).contains(search))
					{
						checkArrayList.remove(j);
						j--;
					}
				}
			}
			else
			{
				search = String.valueOf(search.charAt(0));
				for (int j = 0; j < checkArrayList.size(); j++)
				{
					if (!checkArrayList.get(j).contains(search))
					{
						checkArrayList.remove(j);
						j--;
					}
				}
			}
		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event)
	{
		// TODO Auto-generated method stub

		if(mSearchText.hasFocus())
		mSearchText.clearFocus();
		return mGesture.onTouchEvent(event);
	}

	@Override
	public boolean onDown(MotionEvent e)
	{
		// TODO Auto-generated method stub
		util(e);
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e)
	{
		// TODO Auto-generated method stub

	}

	@Override
	public boolean onSingleTapUp(MotionEvent e)
	{
		// TODO Auto-generated method stub

		mImageView.setImageResource(R.drawable.contact_list_scroll_normal);
		mIcon.setVisibility(View.INVISIBLE);
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY)
	{
		util(e2);
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e)
	{
		// TODO Auto-generated method stub
		mImageView.setImageResource(R.drawable.contact_list_scroll_normal);
		mIcon.setVisibility(View.INVISIBLE);
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY)
	{
		// TODO Auto-generated method stub
		mImageView.setImageResource(R.drawable.contact_list_scroll_normal);
		mIcon.setVisibility(View.INVISIBLE);
		return false;
	}

	public void util(MotionEvent e2)
	{
		//获取触摸点在导航图片中的位置
		int i = (int) (e2.getY() - mImageView.getTop());

		

		mImageView.setImageResource(R.drawable.contact_list_scroll_pressed);

		int pos;
		int count;
		if (0 <= i && i <= 30)
		{
			mIcon.setText("搜");
			mIcon.setVisibility(View.VISIBLE);
			mListView.setSelectionFromTop(0, 0);
		}
		else
		{
			count = (int) ((i - 31) / ((float) (mImageView.getHeight() - 62) / 26f));

			if (0 <= count && count < 26)
			{
				mIcon.setText(english[count]);

				mIcon.setVisibility(View.VISIBLE);
				pos = mAdapter.checkSection(english[count]) + 1;
				if (pos >= 0) mListView.setSelectionFromTop(pos, 0);
			}
			else
			{
				mIcon.setVisibility(View.VISIBLE);
				mIcon.setText("#");
			}
		}

	}

}




二、Sort.java

package com.example.tongxunlu;

import java.util.ArrayList;

import net.sourceforge.pinyin4j.PinyinHelper;

public class Sort
{
	
	/**中英文混合排序
	 * 
	 * @param strArr 原始的通讯录名单
	 * @return   排序后的通讯录名单
	 */
	public String[] autoSort(String[] strArr)
	{
		String temp = "";
		
		String headchar1 ;
		
		String headchar2 ;
		
		for (int i = 0; i < strArr.length; i++)
		{
			for (int j = i; j < strArr.length; j++)
			{
				headchar1 =  getPinYinHeadChar(strArr[i]).toUpperCase();
				headchar2 =  getPinYinHeadChar(strArr[j]).toUpperCase();
				if (headchar1.charAt(0) > headchar2.charAt(0))
				{
					temp = strArr[i];
					strArr[i] = strArr[j];
					strArr[j] = temp;
				}
			}
		}
		return strArr;
	}

	/**得到当前联系人名称的的一个汉字的首字母
	 * 
	 * @param str  联系人名称
	 * @return 首字母
	 */
	public String getPinYinHeadChar(String str)
	{
		String convert = "";
		char word = str.charAt(0);
		String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
		if(pinyinArray!= null)
			convert = String .valueOf(pinyinArray[0].charAt(0));
		else {
			convert = String .valueOf(word);
		}
		return convert;
	}

	/**实现数据分组
	 * 
	 * @param strArr 排序后的通讯录名单
	 * @return  对数据添加了分组字母的ArrayList(如在所有首字母为B的名单组之前添加一个B实现分组)
	 */
	public ArrayList<String> addChar(String[] strArr)
	{
		String headchar = "" ;
		ArrayList<String> list = new ArrayList<String>();
		int j= 0;
		for (int i = 0; i < strArr.length; i++)
		{
			headchar = String.valueOf(getPinYinHeadChar(strArr[i]).charAt(0)).toUpperCase();
			if(!list.contains(headchar))
			{
				list.add(headchar);
				list.add(strArr[i]);
			}
			else {
				list.add(strArr[i]);
			}
		}
		return list;
	}
	
	
	public ArrayList<String> toArrayList(String[] str)
	{
		ArrayList<String> arrayList = new ArrayList<String>();
		for(int i = 0; i<str.length;i++)
			arrayList.add(str[i]);
		return arrayList;
			
	}
	
	/**
	 * 
	 * @param str联系人名称
	 * @return 联系人名称中每个汉字的首字母
	 */
	public String getAllPinYinHeadChar(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;
		}
}


三、MyAdapter.java

package com.example.tongxunlu;

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MyAdapter extends ArrayAdapter<String>
{

	
	public String[] sections;

	public ArrayList<String> mObject;

	public HashMap<String, Integer> alphaIndexer;

	private View view = null;
	
	private TextView tView = null;
	
	private ArrayList<String> arrayList = new ArrayList<String>();

	private String[] english = {"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"};

	public MyAdapter(Context context, int textViewResourceId,
			ArrayList<String> objects)
	{
		super(context, textViewResourceId, objects);
		// TODO Auto-generated constructor stub
		initArrayList();
		mObject = objects;
	}

	@Override
	/**
	 * 添加item时判断,如果读取到的数据可以在arrayList中找到(即大写的单独字母),则添加为标题,否则是内容
	 * 
	 */
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// TODO Auto-generated method stub

		if (arrayList.contains(getItem(position)))
		{
			view = LayoutInflater.from(getContext()).inflate(
					R.layout.list_item_tag, null);
		}
		else
		{
			view = LayoutInflater.from(getContext()).inflate(
					R.layout.list_item, null);
		}

		tView = (TextView) view
				.findViewById(R.id.group_list_item_text);
		tView.setText(getItem(position));

		return view;
	}

	/**
	 * 根据字母导航所点击的字母,锁定名单中对应标题的位置
	 * @param str  所点击的字母
	 * @return     返回字母在数据源中的位置。
	 */
	public int checkSection(String str)
	{

		for (int i = 0; i < mObject.size(); i++)
		{
			if (mObject.get(i).equals(str))
				return i;
		}
		return -1;
	}

	/**
	 * 讲26字母添加进list中,方便getView判断
	 */
	public void initArrayList()
	{
		for (int i = 0; i < english.length; i++)
			arrayList.add(english[i]);
	}

}












  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值