編輯:關於Android編程
在上一篇學習ListView的時候,看到在API中獲取聯系人的例子已經不被官方推薦了。於是,手癢又查了查,看看使用Android如何獲取聯系人信息。這篇可以說著對ListView繼續深入學習,也是對android中訪問聯系人信息的學習。
在學習的過程中參考了很多資料,其中寫得比較好的是這一篇http://xys289187120.blog.51cto.com/3361352/656766
我的例子也基本上是模仿他寫的。
下面看代碼
package com.example.contactlist;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MainActivity extends ListActivity {
Context myContext = null;
MyListAdapter myListAdapter = null;
TextView name = null;
TextView number = null;
//這兩個List用於暫時存儲聯系人的名字和號碼
List myContactName = new ArrayList();
List myContactNumber = new ArrayList();
public void onCreate(Bundle savedInstanceState) {
myContext = this;
//使用getContentResolver方法來讀取聯系人的表
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
while(cursor.moveToNext()){
//聯系人的ID
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
//聯系人的名稱
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
//聯系人的電話
String number = "";
//聯系人是否有電話號碼
int isHas = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts. HAS_PHONE_NUMBER)));
if(isHas>0){
Cursor c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = " + id,null,null);
while(c.moveToNext()){
number += c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))+" ";
}
c.close();
}
myContactName.add(name);
myContactNumber.add(number);
}
cursor.close();
myListAdapter = new MyListAdapter(this);
setListAdapter(myListAdapter);
super.onCreate(savedInstanceState);
}
//定義一個BaseAdpter的子類,並重寫getView方法
class MyListAdapter extends BaseAdapter {
public MyListAdapter(Context context){
myContext = context;
}
public int getCount() {
// TODO Auto-generated method stub
return myContactName.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){
//將List布局文件實例化為一個View
convertView = LayoutInflater.from(myContext).inflate(R.layout.list, null);
name = (TextView) convertView.findViewById(R.id.name);
number = (TextView) convertView.findViewById(R.id.number);
}
name.setText(myContactName.get(position));
number.setText(myContactNumber.get(position));
return convertView;
}
}
}
相對於前一篇的區別是,這次的代碼中定義了一個BaseAdpter的子類,並重寫了getView方法。
還有一點就是
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
這一句代碼中,我們通過getContentResolver()方法來讀取聯系人數據庫中的內容。getContentResolver可以讀取通過ContentProvider提供的數據。這裡先不細說了。
這個程序運行起來,剛開始是沒問題的,所有的聯系人都讀取出來了。但是,當我向下拖動ListView的時候,發現,有的聯系人的信息刷新變成了別的聯系人,有的聯系人順序也變了,總之一拖動ListView就會出現一些比較奇怪的現象。
我把這個問題放到一些論壇上和大家討論了一下。目前個人認為比較靠譜的解釋是我在getView中的寫法會導致Item中的View重新初始化。。所以會導致一些聯系人變了。。(誰有更好的解釋留言告訴我一下)
我試了一種比較好的解決方法就是加上一個靜態類ViewHolder,修改後代碼如下
package com.example.contactlist;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MainActivity extends ListActivity {
Context myContext = null;
MyListAdapter myListAdapter = null;
ViewHolder viewHolder = null;
List myContactName = new ArrayList();
List myContactNumber = new ArrayList();
public void onCreate(Bundle savedInstanceState) {
myContext = this;
//使用getContentResolver方法來讀取聯系人的表
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
while(cursor.moveToNext()){
//聯系人的ID
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
//聯系人的名稱
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
//聯系人的電話
String number = "";
//聯系人是否有電話號碼
int isHas = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts. HAS_PHONE_NUMBER)));
if(isHas>0){
Cursor c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = " + id,null,null);
while(c.moveToNext()){
number += c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))+" ";
}
c.close();
}
myContactName.add(name);
myContactNumber.add(number);
}
cursor.close();
myListAdapter = new MyListAdapter(this);
setListAdapter(myListAdapter);
super.onCreate(savedInstanceState);
}
class MyListAdapter extends BaseAdapter {
public MyListAdapter(Context context){
myContext = context;
}
public int getCount() {
// TODO Auto-generated method stub
return myContactName.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(myContext).inflate(R.layout.list, null);
viewHolder.name = (TextView) convertView.findViewById(R.id.name);
viewHolder.number = (TextView) convertView.findViewById(R.id.number);
convertView.setTag(viewHolder);
}else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.name.setText(myContactName.get(position));
viewHolder.number.setText(myContactNumber.get(position));
return convertView;
}
}
private static class ViewHolder
{
TextView name;
TextView number;
}
}
加上了這個類之後,我再試了試發現ListView拖動的時候比較平滑,也沒有出現過聯系人位置改變的情況了。
由於這個涉及到聯系人信息所以就不截圖了,但是代碼保證是可用的。
附上布局文件:
Android TextView設置不同的顏色字體
這裡記錄一個比較方便的方式來解決Textview設置不同顏色的字體的方法。可能第一反應是布局的嵌套,這個方法肯定可以啊,但是肯定不推薦啊,布局要盡量減少布局的嵌套,其次,
RxAndroid 實踐快速入門
一、RxJava概念RxJava官方定義一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫。用一個詞概括:異步,也就是說RxJava也可以理解為一
【項目架構】Android MVP 和MVVM框架模式 學習實例Demo之mvp篇
隨著移動開發的不斷演進,項目開發設計模式也變的越來越新穎,越來越便捷。而各個團隊都在追求良好的項目架構,不僅能加快工程的進度,也對後續項目的維護和擴展起來很重要的做用。但
Android實現圓角矩形和圓形ImageView的方式
Android中實現圓角矩形和圓形有很多種方式,其中最常見的方法有ImageLoader設置Option和自定義View。 1.ImageLoader加載圖片public