首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

仿照微信好友列表功能(数据从手机中读取)

2013-01-08 
模仿微信好友列表功能(数据从手机中读取)http://www.uml.org.cn/mobiledev/201110121.asphttp://blog.csdn

模仿微信好友列表功能(数据从手机中读取)

http://www.uml.org.cn/mobiledev/201110121.asp

http://blog.csdn.net/jiahui524/article/details/7785606

感谢这两位的博客:

?

?

模仿微信好友列表功能(数据从手机中读取),实现汉首字母排序筛选:

用到了一个pinyin4j-2.5.0.jar这个包

?

这个包的介绍:http://sourceforge.net/projects/pinyin4j/files/

?

其中还有一个 ContentResolver的知识点:

http://www.cnblogs.com/ruiyi1987/archive/2011/06/20/2084925.html

?

这篇文章中用到这样一个查询条件:

? String[]?proj1=new?String[]{ContactsContract.Contacts.DISPLAY_NAME,
????????????????????????????????????ContactsContract.Contacts.HAS_PHONE_NUMBER,
????????????????????????????????????ContactsContract.Contacts.LOOKUP_KEY};

ContactsContract.Contacts已经不推荐使用,现在推荐使用phone

?

下面是代码:

?

main.xml

?

<?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="fill_parent"    android:orientation="vertical" >    <FrameLayout        android:id="@+id/llParent"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:orientation="vertical" >        <ListView            android:id="@+id/lvShow"            android:layout_width="fill_parent"            android:layout_height="fill_parent" />        <TextView            android:id="@+id/tvLetter"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:background="@drawable/show_head_toast_bg"            android:gravity="center"            android:maxWidth="70dip"            android:minWidth="70dip"            android:padding="10dip"            android:textColor="#99FFFFFF"            android:textSize="50sp" >        </TextView>        <mypack.aaron.conact.MySideBar            android:id="@+id/myView"            android:layout_width="30dip"            android:layout_height="fill_parent"            android:layout_gravity="right" >        </mypack.aaron.conact.MySideBar>    </FrameLayout></LinearLayout>

? ?list_item.xml

?

<?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:descendantFocusability="blocksDescendants"    android:orientation="vertical">    <TextView        android:id="@+id/tv_catalog"        style="@style/MMListCatalog"        android:layout_height="wrap_content"        android:paddingRight="4.0dip" />    <LinearLayout        android:id="@+id/contactitem_layout"        style="@style/MMListItem"        android:layout_height="56.0dip"        android:background="@drawable/mm_listitem"        android:paddingLeft="8.0dip" >        <ImageView            android:id="@+id/contactitem_avatar_iv"            android:layout_width="40.0dip"            android:layout_height="40.0dip" android:src="@drawable/default_avatar" />        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1.0"            android:orientation="vertical"            android:paddingLeft="8.0dip" >            <TextView                android:id="@+id/tv_nick"                style="@style/MMFontTitleInList"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:singleLine="true" android:text="姓名" />            <TextView                android:id="@+id/tv_mobile"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_weight="1"                android:singleLine="true"                android:text="13123456789"                android:textColor="#666666" />        </LinearLayout>        <ImageButton            android:id="@+id/imgbtn_nav"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:layout_marginRight="5dip"            android:background="@drawable/nav_left"            android:focusable="false"            android:focusableInTouchMode="false" />    </LinearLayout></LinearLayout>

? ? style.xml

?

<?xml version="1.0" encoding="utf-8"?><resources>     <!-- 联系分组样式 -->    <style name="MMListItem">        <item name="android:gravity">center_vertical</item>        <item name="android:orientation">horizontal</item>        <item name="android:paddingLeft">4.0dip</item>        <item name="android:paddingTop">4.0dip</item>        <item name="android:paddingRight">4.0dip</item>        <item name="android:paddingBottom">4.0dip</item>        <item name="android:layout_width">fill_parent</item>        <item name="android:layout_height">wrap_content</item>    </style>    <style name="MMFriendListItem">        <item name="android:gravity">center_vertical</item>        <item name="android:orientation">horizontal</item>        <item name="android:paddingLeft">16.0dip</item>        <item name="android:paddingTop">6.0dip</item>        <item name="android:paddingRight">6.0dip</item>        <item name="android:paddingBottom">6.0dip</item>        <item name="android:layout_width">fill_parent</item>        <item name="android:layout_height">wrap_content</item>    </style>    <style name="MMListCatalog">        <item name="android:textSize">14.0dip</item>        <item name="android:textStyle">bold</item>        <item name="android:textColor">#ff595c61</item>        <item name="android:gravity">center_vertical</item>        <item name="android:orientation">horizontal</item>        <item name="android:background">#ffced2d7</item>        <item name="android:paddingLeft">10.0dip</item>        <item name="android:paddingTop">2.0dip</item>        <item name="android:paddingBottom">2.0dip</item>        <item name="android:layout_width">fill_parent</item>        <item name="android:layout_height">wrap_content</item>    </style>    <style name="MMFontTitleInList">        <item name="android:textSize">16.0dip</item>        <item name="android:textColor">#ff595c61</item>        <item name="android:ellipsize">end</item>        <item name="android:gravity">center_vertical</item>        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:singleLine">true</item>    </style>    <style name="MMFontTipInList">        <item name="android:textSize">14.0dip</item>        <item name="android:textColor">#fff</item>        <item name="android:ellipsize">end</item>        <item name="android:gravity">center_vertical</item>        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:singleLine">true</item>    </style></resources>

?PinyinUtils.java?

这个java文件是生成汉字首字母拼音

?

??public class PinyinUtils {

// 获得汉语拼音首字母public static String getAlpha(String chines) {String pinyinName = "";char[] nameChar = chines.toCharArray();HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);for (int i = 0; i < nameChar.length; i++) {if (nameChar[i] > 128) {try {pinyinName += PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0].charAt(0);} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}} else {pinyinName += nameChar[i];}}return pinyinName;}/** * 将字符串中的中文转化为拼音,其他字符不变 *  * @param inputString * @return */public static String getPingYin(String inputString) {HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();format.setCaseType(HanyuPinyinCaseType.LOWERCASE);format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);format.setVCharType(HanyuPinyinVCharType.WITH_V);char[] input = inputString.trim().toCharArray();String output = "";try {for (int i = 0; i < input.length; i++) {if (java.lang.Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);output += temp[0];} elseoutput += java.lang.Character.toString(input[i]);}} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}return output;}/** * 汉字转换位汉语拼音首字母,英文字符不变 *  * @param chines *            汉字 * @return 拼音 */public static String converterToFirstSpell(String chines) {String pinyinName = "";char[] nameChar = chines.toCharArray();HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);for (int i = 0; i < nameChar.length; i++) {if (nameChar[i] > 128) {try {pinyinName += PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0].charAt(0);} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}} else {pinyinName += nameChar[i];}}return pinyinName;}}

? ?MySideBar.java

? 右边拼音

?

public class MySideBar  extends View{OnTouchingLetterChangedListener onTouchingLetterChangedListener;// 26个字母public static String[] b = { "#", "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" };int choose = -1;Paint paint = new Paint();public MySideBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public MySideBar(Context context, AttributeSet attrs) {super(context, attrs);}public MySideBar(Context context) {super(context);}/** * 重写这个方法 */protected void onDraw(Canvas canvas) {super.onDraw(canvas);if (showBkg) {canvas.drawColor(Color.parseColor("#40000000"));}int height = getHeight();int width = getWidth();int singleHeight = height / b.length;for (int i = 0; i < b.length; i++) {paint.setColor(Color.BLACK);// paint.setColor(Color.WHITE);paint.setTypeface(Typeface.DEFAULT_BOLD);paint.setAntiAlias(true);paint.setTextSize(20);if (i == choose) {paint.setColor(Color.parseColor("#3399ff"));paint.setFakeBoldText(true);}float xPos = width / 2 - paint.measureText(b[i]) / 2;float yPos = singleHeight * i + singleHeight;canvas.drawText(b[i], xPos, yPos, paint);paint.reset();}}private boolean showBkg = false;@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {final int action = event.getAction();final float y = event.getY();final int oldChoose = choose;final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;final int c = (int) (y / getHeight() * b.length);switch (action) {case MotionEvent.ACTION_DOWN:showBkg = true;if (oldChoose != c && listener != null) {if (c > 0 && c < b.length) {listener.onTouchingLetterChanged(b[c]);choose = c;invalidate();}}break;case MotionEvent.ACTION_MOVE:if (oldChoose != c && listener != null) {if (c > 0 && c < b.length) {listener.onTouchingLetterChanged(b[c]);choose = c;invalidate();}}break;case MotionEvent.ACTION_UP:showBkg = false;choose = -1;invalidate();break;}return true;}@Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}/** * 向外公开的方法 *  * @param onTouchingLetterChangedListener */public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) {this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;}/** * 接口 *  * @author coder *  */public interface OnTouchingLetterChangedListener {public void onTouchingLetterChanged(String s);}}

??public class PinyinComparator implements Comparator{

  /** 按首字母排序**/@Overridepublic int compare(Object o1, Object o2) { String str1 = PinyinUtils.getPingYin((String) o1);     String str2 = PinyinUtils.getPingYin((String) o2);     return str1.compareTo(str2);}////@Override//public int compare(Object o1, Object o2) {// String str1 = PinyinUtils.getPingYin(((UserInfo) o1).getPy());//     String str2 = PinyinUtils.getPingYin(((UserInfo) o2).getPy());//     return str1.compareTo(str2);//}}
?

?

?

? 最后就是activity:

?

public class ContactsActivity extends Activity implements OnTouchingLetterChangedListener { private ListView lv_list; /**联系人显示名称**/   private static final int PHONES_DISPLAY_NAME_INDEX = 0;   /**电话号码**/   private static final int PHONES_NUMBER_INDEX = 1;   /**头像ID**/   private static final int PHONES_PHOTO_ID_INDEX = 2;   /**联系人的ID**/   private static final int PHONES_CONTACT_ID_INDEX = 3;   /**联系人名称**/   private ArrayList<String> mContactsName = new ArrayList<String>();   /**联系人头像**/   private ArrayList<String> mContactsNumber = new ArrayList<String>();   /**联系人头像**/   private ArrayList<Bitmap> mContactsPhonto = new ArrayList<Bitmap>();  /**拼音**/ private ArrayList<String> mPy=new ArrayList<String>(); /**左侧拼音字母**/ private MySideBar myView; /**显示到屏幕中间的拼音**/ private TextView overlay; private OverlayThread overlayThread = new OverlayThread();    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        lv_list=(ListView)findViewById(R.id.lv_lsit);        overlay=(TextView)findViewById(R.id.tvLetter);        lv_list.setTextFilterEnabled(true);overlay.setVisibility(View.INVISIBLE);//默认隐藏                myView = (MySideBar) findViewById(R.id.myView);myView.setOnTouchingLetterChangedListener(this);  ContentResolver resolver = getContentResolver();          String[] proj1=new String[]{Phone.DISPLAY_NAME,                Phone.NUMBER,Phone.PHOTO_ID,Phone.CONTACT_ID,              };        Cursor curContacts=resolver.query(Phone.CONTENT_URI,proj1, null, null, null);        if(curContacts.getCount()>0){            while(curContacts.moveToNext()){              //得到手机号码                  String phoneNumber = curContacts.getString(PHONES_NUMBER_INDEX);                //当手机号码为空的或者为空字段 跳过当前循环                  if (TextUtils.isEmpty(phoneNumber)){                    continue;                 }                  //得到联系人名称                  String contactName = curContacts.getString(PHONES_DISPLAY_NAME_INDEX);                 //拼音                String py=PinyinUtils.getAlpha(contactName);                //得到联系人ID                  Long contactid = curContacts.getLong(PHONES_CONTACT_ID_INDEX);                  //得到联系人头像ID                  Long photoid = curContacts.getLong(PHONES_PHOTO_ID_INDEX);                  //得到联系人头像Bitamp                  Bitmap contactPhoto = null;                  //photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的                  if(photoid > 0 ) {                      Uri uri =ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,contactid);                      InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(resolver, uri);                      contactPhoto = BitmapFactory.decodeStream(input);                  }else {                      contactPhoto = BitmapFactory.decodeResource(getResources(), R.drawable.contact_photo);                  }                  mContactsName.add(contactName);                mContactsPhonto.add(contactPhoto);                mContactsNumber.add(phoneNumber);                mPy.add(py);                                        } Collections.sort(mContactsName, new PinyinComparator()); //ArrayList按首字母拼音排序            curContacts.close();        }      ListViewAdapter ltAdapter=new ListViewAdapter();      lv_list.setAdapter(ltAdapter);    }    /**绑定数据**/    public class ListViewAdapter extends BaseAdapter{ @Overridepublic int getCount() {// TODO Auto-generated method stubreturn mContactsName.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {LayoutInflater inflater =getLayoutInflater();              // 使用View的对象itemView与R.layout.item关联  if(convertView==null){convertView=inflater.inflate(R.layout.list_item, null);  }             // 通过findViewById()方法实例R.layout.item内各组件              TextView tvName = (TextView) convertView.findViewById(R.id.tv_nick);              TextView tvPhone=(TextView) convertView.findViewById(R.id.tv_mobile);            ImageView iv_pic = (ImageView) convertView.findViewById(R.id.contactitem_avatar_iv);              TextView tv_catalog=(TextView)convertView.findViewById(R.id.tv_catalog);                        /*首字拼音*/            String catalog = PinyinUtils.converterToFirstSpell(mContactsName.get(position).substring(0, 1));                        if(position==0){            tv_catalog.setVisibility(View.VISIBLE);    tv_catalog.setText(catalog);            }else {            /*下一个汉字首字拼音,如果两个汉字的首字母相等,下一个汉字的tv_catalog隐藏,这里其实就是把相同首字母的汉字叠加在一起*/    String lastCatalog = PinyinUtils.converterToFirstSpell(mContactsName.get(position - 1)).substring(0,1);    if (catalog.equals(lastCatalog)) {    tv_catalog.setVisibility(View.GONE);    } else {    tv_catalog.setVisibility(View.VISIBLE);    tv_catalog.setText(catalog);    }    }                        tvName.setText(mContactsName.get(position));              iv_pic.setImageBitmap(mContactsPhonto.get(position));             tvPhone.setText(mContactsNumber.get(position));            return convertView;  }    }/*下面是触摸左侧拼音*/    private Handler handler = new Handler() {};private class OverlayThread implements Runnable {public void run() {overlay.setVisibility(View.GONE);}}    /**字母触摸事件**/@Overridepublic void onTouchingLetterChanged(String s) {Log.i("coder", "s:" + s);overlay.setText(s);overlay.setVisibility(View.VISIBLE);handler.removeCallbacks(overlayThread);handler.postDelayed(overlayThread, 1000);if (alphaIndexer(s) > 0) {int position = alphaIndexer(s);Log.i("coder", "position:" + position);lv_list.setSelection(position);}}//根据 字母的值找到mPy存储的汉字首字母拼音的索引,listView中根据这个索引定位显示public int alphaIndexer(String s) {int position = 0;for (int i = 0; i < mContactsPhonto.size(); i++) {if (mPy.get(i).startsWith(s)) {position = i;break;}}Log.i("coder", "i" + position + mPy.get(position));return position;}    }

?经过了手机测试成功,代码比较臃肿,还没有实现输入筛选条件查询,正在研究中

热点排行