編輯:關於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用於暫時存儲聯系人的名字和號碼 ListmyContactName = 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; ListmyContactName = 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拖動的時候比較平滑,也沒有出現過聯系人位置改變的情況了。
由於這個涉及到聯系人信息所以就不截圖了,但是代碼保證是可用的。
附上布局文件:
這裡記錄一個比較方便的方式來解決Textview設置不同顏色的字體的方法。可能第一反應是布局的嵌套,這個方法肯定可以啊,但是肯定不推薦啊,布局要盡量減少布局的嵌套,其次,
一、RxJava概念RxJava官方定義一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫。用一個詞概括:異步,也就是說RxJava也可以理解為一
隨著移動開發的不斷演進,項目開發設計模式也變的越來越新穎,越來越便捷。而各個團隊都在追求良好的項目架構,不僅能加快工程的進度,也對後續項目的維護和擴展起來很重要的做用。但
Android中實現圓角矩形和圓形有很多種方式,其中最常見的方法有ImageLoader設置Option和自定義View。 1.ImageLoader加載圖片public