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

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

2014-03-03 20:59 615 查看
主要实现功能:

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

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

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

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

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

程序功能效果如下













代码结构:







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



activity_main.xml 主界面

[html] view
plaincopy

<?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当点击导航时,显示在屏幕中间的提示图标

[html] view
plaincopy

<?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名单组的标题,即对应的首字母

[html] view
plaincopy

<?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

[html] view
plaincopy

<?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搜索框

[html] view
plaincopy

<?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

[java] view
plaincopy

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

[java] view
plaincopy

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

[java] view
plaincopy

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]);

}

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