android提供了本地数据库的查询uri,可以查询出数据:
采用一个AsyncQueryHandler来进行查询, AsyncQueryHandler自己开启了线程来进行数据查询,很方便
protected AsyncQueryHandler mQueryHandler;
protected final void queryPersonal() {
mQueryHandler.startQuery(QUERY_TOKEN, null, ContactsContract.Contacts.CONTENT_URI,
Personal.CONTACTS_SUMMARY_PROJECTION, null, null, getSortOrder(ContactsContract.Contacts.DISPLAY_NAME));
}
protected static String getSortOrder(String fieldName) {
//substr为截取函数,取第一个字母
//COLLATE主要用于对字符进行排
//COLLATE LOCALIZED 按本地语言进行排序
return "CASE WHEN substr(UPPER(" + fieldName + "), 1, 1) BETWEEN 'A' AND 'Z' THEN 1 else 10 END," +
fieldName + " COLLATE LOCALIZED ASC";
}
protected final class MyHandler extends AsyncQueryHandler {
/**
* Asynchronous query handler constructor.
*/
public MyHandler(Context context) {
super(context.getContentResolver());
}
/**
* On query completion.
*/
@Override
<strong>protected void onQueryComplete(int token, Object cookie, Cursor cursor) </strong>{ //handler查询完的回调
if (cursor == null || cursor.isClosed()) {
return;
}
if (!isFinishing()) {
setLoading(false);
if (mAdapter != null) {
mAdapter.setLoading(false);
mAdapter.changeCursor(cursor);
}
if (cursor.getCount() == 0) {
mEmtytext.setVisibility(View.VISIBLE);
} else {
mEmtytext.setVisibility(View.INVISIBLE);
}
} else {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
}
}
这个Layout是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:rcm="http://schemas.android.com/apk/res/com.ringcentral.android"
android:id="@+id/contact_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bgColorMain"
android:orientation="vertical">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@android:color/transparent"
android:descendantFocusability="afterDescendants"
android:divider="@null"
android:fastScrollEnabled="true"
android:listSelector="@drawable/bg_list_item_selector" />
<RelativeLayout
android:id="@+id/no_contact_indication"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/emptyListText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:singleLine="true"
android:text="No Contacts"
android:textColor="@color/text_no_items"
android:textSize="20sp" />
<ProgressBar
android:id="@+id/loading"
style="@style/RCMProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
然后是list adapter的写法:
protected static final class SectionedContactListItemCache {
public TextView sectionHeader;
public TextView nameView;
public TextView typeView;
public ImageView photoView;
public ImageView detailItemIcon;
<span style="white-space:pre"> </span>public View nameTypeWrapper;
}
protected final class ContactsAdapter extends ResourceCursorAdapter {
public ContactsAdapter(Context context) {
super(context, R.layout.contacts_list_item_photo,null);
}
@Override
public void changeCursor(Cursor c) {
super.changeCursor(c);
}
protected String getTitle(String displayName) {
String title;
/** check if the first letter is English letter */
Matcher matcher = mPattern.matcher(displayName);
if (!matcher.find()) {
title = NONE_ENGLISH_LETTER_TITLE;
} else {
title = displayName.trim().substring(0, 1).toUpperCase(Locale.US);
}
return title;
}
protected String getDisplayName(Cursor c) {
String displayName = c.getString(Personal.NAME_COLUMN_INDEX);
if(TextUtils.isEmpty(displayName)) {
return "";
}
return displayName;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final SectionedContactListItemCache cache = (SectionedContactListItemCache) view.getTag();
cache.typeView.setVisibility(View.GONE);
cache.photoView.setVisibility(View.VISIBLE);
String name = cursor.getString(Personal.NAME_COLUMN_INDEX);
if (TextUtils.isEmpty(name)) {
cache.nameView.setText(R.string.contact_no_name);
} else {
cache.nameView.setText(name);
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = super.newView(context, cursor, parent);
final SectionedContactListItemCache cache = new SectionedContactListItemCache();
cache.nameTypeWrapper = view.findViewById(R.id.name_type);
cache.sectionHeader = (TextView) view.findViewById(R.id.txtSectionHeader);
cache.nameView = (TextView) view.findViewById(R.id.name);
cache.typeView = (TextView) view.findViewById(R.id.type);
cache.photoView = (ImageView) view.findViewById(R.id.photo);
cache.detailItemIcon = (ImageView) view.findViewById(R.id.contacts_detail_item_icon);
view.setTag(cache);
return view;
}
}//end of adapter
item adapter的layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/txtSectionHeader"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_section_height"
android:background="@drawable/bg_contacts_section_header"
android:gravity="center_vertical|left"
android:paddingLeft="@dimen/default_padding_to_side"
android:textColor="@color/contacts_text_separator_text_color"
android:textSize="@dimen/font_size_medium" />
<RelativeLayout
android:id="@+id/contact_item"
android:layout_width="match_parent"
android:layout_height="@dimen/general_list_view_item_height">
<ImageView
android:id="@+id/photo"
android:layout_width="@dimen/favorites_item_picture_width"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignWithParentIfMissing="true"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:layout_marginLeft="@dimen/contact_photo_margin_left_right"
android:scaleType="fitCenter"
/>
<!-- this icon may be added in next version, and now it would be hidden -->
<ImageView
android:id="@+id/contacts_detail_item_icon"
android:layout_width="50dip"
android:layout_height="60dip"
android:layout_alignParentRight="true"
android:layout_marginRight="0dip"
android:cropToPadding="true"
android:duplicateParentState="false"
android:paddingBottom="3dip"
android:paddingTop="3dip"
android:scaleType="fitCenter"
android:src="@drawable/ic_list_link"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/name_type"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignWithParentIfMissing="true"
android:layout_toLeftOf="@id/contacts_detail_item_icon"
android:layout_marginLeft="@dimen/contact_photo_margin_left_right"
android:layout_toRightOf="@id/photo"
android:background="@drawable/bg_list_item_divider">
<TextView
android:id="@+id/type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/name"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/contact_type_margin_left_right"
android:ellipsize="marquee"
android:gravity="center_vertical|right"
android:singleLine="true"
android:textColor="@color/refresh_control_text_color"
android:textSize="@dimen/font_size_small" />
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/contact_name_margin_left_right"
android:layout_toLeftOf="@id/type"
android:ellipsize="marquee"
android:gravity="center_vertical|left"
android:singleLine="true"
android:textColor="@color/text_color_main"
android:textSize="@dimen/font_size_medium" />
</RelativeLayout>
</RelativeLayout>
</LinearLayout>