您的位置:首页 > 移动开发 > 微信开发

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

2013-08-01 15:02 736 查看
主要实现功能:

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

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

三、实现搜索功能(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]);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android