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

Android 获取手机通讯录信息 — 头像、姓名和A-Z的快速查询

2014-01-15 16:37 609 查看
首先先看一下效果图再说吧:



具体实现过程如下:

先在AndroidManifest.xml文件中添加读取联系人的权限:

<uses-permission android:name="android.permission.READ_CONTACTS" />


联系人列表对应的适配器:

package com.example.testcontacts.adapter;

import java.util.List;

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

import com.example.testcontacts.R;
import com.example.testcontacts.domain.Contact;

public class ContactAdapter extends ArrayAdapter<Contact> {
private int resource;// 需要渲染的item布局文件
private SectionIndexer mIndexer;// 字母表分组工具

public ContactAdapter(Context context, int textViewResourceId,List<Contact> objects) {
super(context, textViewResourceId, objects);
resource = textViewResourceId;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
Contact contact = getItem(position);
View view = convertView == null ? View.inflate(getContext(),  R.layout.contact_item, null) : convertView;
LinearLayout ll_sort_key = (LinearLayout) view.findViewById(R.id.ll_sort_key);
TextView tv_sort_key = (TextView) view.findViewById(R.id.tv_sort_key);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
TextView tv_number = (TextView) view.findViewById(R.id.tv_number);

tv_name.setText(contact.getName());
tv_number.setText(contact.getNumber());

int section = mIndexer.getSectionForPosition(position);
if (position == mIndexer.getPositionForSection(section)) {
tv_sort_key.setText(contact.getSortKey());
ll_sort_key.setVisibility(View.VISIBLE);
}else{
ll_sort_key.setVisibility(View.GONE);
}
return view;
}

/**给当前适配器传入一个分组工具*/
public void setIndexer(SectionIndexer indexer) {
mIndexer = indexer;
}
}


实体类:

package com.example.testcontacts.domain;

public class Contact {
private String name;// 联系人姓名
private String sortKey;// 排序字母
private String number;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSortKey() {
return sortKey;
}

public void setSortKey(String sortKey) {
this.sortKey = sortKey;
}

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}
}


java类:

package com.example.testcontacts;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AlphabetIndexer;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.testcontacts.adapter.ContactAdapter;
import com.example.testcontacts.domain.Contact;

public class MainActivity extends Activity {
private LinearLayout ll_title;// 分组的布局
private RelativeLayout rl_toast;
private Button btn_alphabet;
private TextView tv_title; // 分组上显示的字母
private TextView tv_toast;
private ListView lv_contacts;// 联系人ListView

private ContactAdapter adapter;// 联系人列表适配器
private AlphabetIndexer indexer;// 用于进行字母表分组
private List<Contact> contacts = new ArrayList<Contact>();// 存储所有手机中的联系人
private String alphabet = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";// 定义字母表的排序规则
private int lastFirstVisibleItem = -1;// 上次第一个可见元素,用于滚动时记录标识。

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

adapter = new ContactAdapter(this, R.layout.contact_item, contacts);
ll_title = (LinearLayout) findViewById(R.id.ll_title);
rl_toast = (RelativeLayout) findViewById(R.id.rl_section_toast);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_toast = (TextView) findViewById(R.id.tv_section_toast);
btn_alphabet = (Button) findViewById(R.id.btn_alphabet);
lv_contacts = (ListView) findViewById(R.id.lv_contacts);

Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursor = getContentResolver().query(uri,
new String[] { "display_name", "sort_key", }, null, null,
"sort_key");
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(0);
String sortKey = getSortKey(cursor.getString(1));
Contact contact = new Contact();
contact.setName(name);
contact.setSortKey(sortKey);
contacts.add(contact);
} while (cursor.moveToNext());
}
startManagingCursor(cursor);
indexer = new AlphabetIndexer(cursor, 1, alphabet);
adapter.setIndexer(indexer);
if (contacts.size() > 0) {
setListViewListener();
setAlpabetListener();
}
}

/** 根据当前的滑动状态来改变分组的显示位置,从而实现挤压动画的效果 */
private void setListViewListener() {
lv_contacts.setAdapter(adapter);
lv_contacts.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int section = indexer.getSectionForPosition(firstVisibleItem);//当前分组所在的位置
int nextSecPosition = indexer.getPositionForSection(section + 1);//找出当前位置所在的分组
if (firstVisibleItem != lastFirstVisibleItem) {
MarginLayoutParams params = (MarginLayoutParams) ll_title
.getLayoutParams();
params.topMargin = 0;
ll_title.setLayoutParams(params);
tv_title.setText(String.valueOf(alphabet.charAt(section)));
}
if (nextSecPosition == firstVisibleItem + 1) {
View childView = view.getChildAt(0);
if (childView != null) {
int titleHeight = ll_title.getHeight();
int bottom = childView.getBottom();
MarginLayoutParams params = (MarginLayoutParams) ll_title
.getLayoutParams();
if (bottom < titleHeight) {
float pushedDistance = bottom - titleHeight;
params.topMargin = (int) pushedDistance;
ll_title.setLayoutParams(params);
} else {
if (params.topMargin != 0) {
params.topMargin = 0;
ll_title.setLayoutParams(params);
}
}
}
}
lastFirstVisibleItem = firstVisibleItem;
}
});
}

/**
* 获取sort key的首个字符,如果是英文字母就直接返回,否则返回#。
* @param sortKeyString 数据库中读取出的sort key
* @return 英文字母或者#
*/
private String getSortKey(String sortKeyString) {
String key = sortKeyString.substring(0, 1).toUpperCase();
if (key.matches("[A-Z]")) {
return key;
}
return "#";
}

/**
* 设置字母表上的触摸事件,根据当前触摸的位置结合字母表的高度,计算出当前触摸在哪个字母上。
* 当手指按在字母表上时,展示弹出式分组。手指离开字母表时,将弹出式分组隐藏。
*/
private void setAlpabetListener() {
btn_alphabet.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
float alphabetHeight = btn_alphabet.getHeight();//获得字母表的总高度
float y = event.getY();//获取到目前手指在字母表上的纵坐标
int sectionPosition = (int) ((y/alphabetHeight)/(1f/27f));//当前手指所在位置(0表在#端,1表示在Z端)。
if (sectionPosition < 0) {
sectionPosition = 0;
} else if (sectionPosition > 26) {
sectionPosition = 26;
}
String sectionLetter = String.valueOf(alphabet.charAt(sectionPosition));
int position = indexer.getPositionForSection(sectionPosition);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://在弹出式分组上显示当前手指所按的字母
btn_alphabet.setBackgroundResource(R.drawable.contact_list_scroll_pressed);
rl_toast.setVisibility(View.VISIBLE);
tv_toast.setText(sectionLetter);
lv_contacts.setSelection(position);//把列表滚动到相应的分组
break;
case MotionEvent.ACTION_MOVE://同ACTION_DOWN
tv_toast.setText(sectionLetter);
lv_contacts.setSelection(position);
break;
default://弹出式分组布局隐藏
btn_alphabet.setBackgroundResource(R.drawable.contact_list_scroll_normal);
rl_toast.setVisibility(View.GONE);
}
return true;
}
});
}
}


样式:

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

<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />

<gradient
android:angle="90"
android:endColor="#8BC4DF"
android:startColor="#8BC4DF" />

<stroke android:width="1dp" />

</shape>


布局文件:

在res/layout中新建一个布局文件,起名为:activity.main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/lv_contacts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:divider="@drawable/divider1"
android:dividerHeight="1dp"
android:fadingEdge="none"
android:scrollbars="none" >
</ListView>

<LinearLayout
android:id="@+id/ll_title"
android:layout_width="fill_parent"
android:layout_height="18dp"
android:layout_alignParentTop="true"
android:background="@drawable/itembg" >

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="14sp" />
</LinearLayout>

<Button
android:id="@+id/btn_alphabet"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:background="@drawable/contact_list_scroll_normal" />

<RelativeLayout
android:id="@+id/rl_section_toast"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:background="@drawable/section_toast"
android:visibility="gone" >

<TextView
android:id="@+id/tv_section_toast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#000"
android:textSize="30sp" />
</RelativeLayout>

</RelativeLayout>


在res/layout中新建一个布局文件,起名为:contact_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
android:id="@+id/ll_sort_key"
android:layout_width="fill_parent"
android:layout_height="18dip"
android:background="@drawable/itembg" >

<TextView
android:id="@+id/tv_sort_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dip"
android:text="A"
android:textColor="#000000"
android:textSize="14sp" />
</LinearLayout>

<LinearLayout
android:id="@+id/ll_name"
android:layout_width="fill_parent"
android:layout_height="50dip" >

<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:src="@drawable/icon" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top"
android:orientation="vertical" >

<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="张三"
android:textColor="#000000"
android:textSize="18sp" />

<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp"
android:text="186057986"
android:textColor="#88000000"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>

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