加载一个联系人的图片变成ListView控件(部分2) [英] Load a contact's picture into ListView (part 2)

查看:334
本文介绍了加载一个联系人的图片变成ListView控件(部分2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经修改<一个href=\"http://stackoverflow.com/questions/8338038/load-a-contacts-picture-into-a-listview-instead-of-the-default\">the code在这个问题上,根据答案在那里,以加载在一个ListView联系人的图片。我越来越Photo_id,并用它来获取联系人的位图,使用loadContactPhoto(ContentResolver的CR,长ID)。问题是,没有ImageView的是得到一个新的形象,虽然照片的身份证始终是不同的。我尝试使用Contact._ID,但仍然只有两个联系人的ImageView的有一个接触的图片,他们都错了。我有评论新线下面我补充道。

下面是编辑后,code:

ContactStock:

 公共类ContactStock {私人字符串名称;
私人串号;
私人位图图片;
公共ContactStock(字符串名称,串号){
    this.name =名称;
    this.number =号;
}公共ContactStock(字符串名称,串号,位图图片){
    this.name =名称;
    this.number =号;
    this.picture =照片;
}公共无效setname可以(字符串名称){
    this.name =名称;
}公共无效setNumber(串号){
    this.number =号;
}公共字符串的getName(){
    返回this.name;
}公共字符串getNumber(){
    返回this.number;
}公共无效setPicture(位图图片){//新方法
    this.picture =图片;
}公共位图Getpicture中(){//新方法
    返回的画面;
}
}

addlistfromcontact:

 公共类addlistfromcontact延伸活动{
私人的ListView善堂;
私人列表&LT; ContactStock&GT; contactstock;
私人光标mCursor;@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    // TODO自动生成方法存根
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.tab_contact_list);
    LST =(ListView控件)findViewById(R.id.tab_contact_list);
    contactstock =新的ArrayList&LT; ContactStock&GT;();    mCursor = managedQuery(ContactsContract.Data.CONTENT_URI,空,
            Data.MIMETYPE +='+ Phone.CONTENT_ITEM_TYPE +',空,
            ContactsContract.Data.DISPLAY_NAME +ASC);    INT数= mCursor.getColumnIndex(Phone.NUMBER);
    INT NAME = mCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
    INT ID = mCursor.getColumnIndex(Contacts.PHOTO_ID); // 新队    而(mCursor.moveToNext()){        字符串phName = mCursor.getString(名);
        串phNumber = mCursor.getString(数);
        长PHID = mCursor.getLong(ID); // 新队        位图phPhoto = loadContactPhoto(getContentResolver(),PHID); // 新队
        Log.d(PHID =,PHID +);        contactstock.add(新ContactStock(phName,phNumber,phPhoto)); //新行编辑
    }
    lst.setAdapter(新ContactListAdapter(addlistfromcontact.this,
            contactstock));
}公共静态位图loadContactPhoto(ContentResolver的CR,长ID){//新方法
    URI URI = ContentUris.withAppendedId(
            ContactsContract.Contacts.CONTENT_URI,ID);
    InputStream的输入= ContactsContract.Contacts
            .openContactPhotoInputStream(CR,URI);
    如果(输入== NULL){
        返回null;
    }
    返回BitmapFactory.de codeStream(输入);
}    }

ContactListAdapter:

 公共类ContactListAdapter扩展ArrayAdapter {
    私人最终活动活动;
    私人最终名单的股票;    公共ContactListAdapter(活动活动,List对象){
        超(活动,R.layout.listview_detail_tab_contact_list,对象);
        this.activity =活动;
        this.stocks =物体;
    }    @覆盖
    公共查看getView(INT位置,查看convertView,父母的ViewGroup){        查看rowView = convertView;
        ContactStockView SV = NULL;
        如果(rowView == NULL){
            //获取该行布局视图的新实例
            LayoutInflater吹气= activity.getLayoutInflater();
            rowView = inflater.inflate(
                    R.layout.listview_detail_tab_contact_list,NULL);            //在对象持有的观点的对象,
            //所以他们并不需要重新牵强
            SV =新ContactStockView();
            sv.name =(TextView中)rowView.findViewById(R.id.contact_name);
            sv.number =(TextView中)rowView.findViewById(R.id.contact_number);
            sv.photo =(ImageView的)rowView.findViewById(R.id.contact_photo);            //缓存标签中的视图对象,
            //这样他们就可以在以后重新访问
            rowView.setTag(SV);
        }其他{
            SV =(ContactStockView)rowView.getTag();
        }
        //从数据对象转移股票数据
        //给视图对象
        ContactStock currentStock =(ContactStock)stocks.get(位置);
        sv.name.setText(currentStock.getName());
        sv.number.setText(currentStock.getNumber());
        sv.photo.setImageBitmap(currentStock.getPicture()); // 新队        // TODO自动生成方法存根
        返回rowView;
    }    保护静态类ContactStockView {
        保护TextView的名称;
        保护TextView的数量;
        保护ImageView的照片; // 新队
    }
}


解决方案

有在code两个问题。第一个是容易克服,其他需要更多的工作。

让我们先从容易的:
该方法 ContactsContract.Contacts.openContactPhotoInputStream(CR,URI)需要联系的URI,而不是照片URI。这是你的电话的ID为 ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,ID)必须有一个接触ID。

您也创造了很多位图遍历结果集时的对象。不要这样做。虽然这可能会在第一次工作,它可能与内存不足错误崩溃时,列表中得到的长。尝试创建尽可能少的位图对象是必要的。那就是:只有那些行可见。当滚动列表视图,你必须回收现有的位图。

I have modified the code in this question ,according to the answers there, in order to load contact's picture on a ListView. I am getting the Photo_id, and use it to get the Bitmap of the contact, using loadContactPhoto(ContentResolver cr, long id) . The problem is that no ImageView is getting a new image, although the photo id is always different. I tried using the Contact._ID, but still only two contacts' ImageView got a contact picture, and they were both wrong. I have commented the new lines I have added below.

Here is the code after the edit:

ContactStock:

public class ContactStock {

private String name;
private String number;
private Bitmap picture;


public ContactStock(String name, String number) {
    this.name = name;
    this.number = number;
}

public ContactStock(String name, String number, Bitmap photo) {
    this.name = name;
    this.number = number;
    this.picture = photo;
}

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

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

public String getName() {
    return this.name;
}

public String getNumber() {
    return this.number;
}

public void setPicture(Bitmap picture) { // NEW METHOD
    this.picture = picture;
}

public Bitmap getPicture() { // NEW METHOD
    return picture;
}
}

addlistfromcontact:

    public class addlistfromcontact extends Activity {
private ListView lst;
private List<ContactStock> contactstock;
private Cursor mCursor;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tab_contact_list);
    lst = (ListView) findViewById(R.id.tab_contact_list);
    contactstock = new ArrayList<ContactStock>();

    mCursor = managedQuery(ContactsContract.Data.CONTENT_URI, null,
            Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null,
            ContactsContract.Data.DISPLAY_NAME + " ASC");

    int number = mCursor.getColumnIndex(Phone.NUMBER);
    int name = mCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
    int id = mCursor.getColumnIndex(Contacts.PHOTO_ID); // NEW LINE

    while (mCursor.moveToNext()) {

        String phName = mCursor.getString(name);
        String phNumber = mCursor.getString(number);
        long phId = mCursor.getLong(id); // NEW LINE

        Bitmap phPhoto = loadContactPhoto(getContentResolver(), phId); // NEW LINE
        Log.d("phId=", phId + "");

        contactstock.add(new ContactStock(phName, phNumber, phPhoto)); // NEW LINE EDIT
    }
    lst.setAdapter(new ContactListAdapter(addlistfromcontact.this,
            contactstock));
}

public static Bitmap loadContactPhoto(ContentResolver cr, long id) { // NEW METHOD
    Uri uri = ContentUris.withAppendedId(
            ContactsContract.Contacts.CONTENT_URI, id);
    InputStream input = ContactsContract.Contacts
            .openContactPhotoInputStream(cr, uri);
    if (input == null) {
        return null;
    }
    return BitmapFactory.decodeStream(input);
}

    }

ContactListAdapter:

public class ContactListAdapter extends ArrayAdapter {
    private final Activity activity;
    private final List stocks;

    public ContactListAdapter(Activity activity, List objects) {
        super(activity, R.layout.listview_detail_tab_contact_list, objects);
        this.activity = activity;
        this.stocks = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View rowView = convertView;
        ContactStockView sv = null;
        if (rowView == null) {
            // Get a new instance of the row layout view
            LayoutInflater inflater = activity.getLayoutInflater();
            rowView = inflater.inflate(
                    R.layout.listview_detail_tab_contact_list, null);

            // Hold the view objects in an object,
            // so they don't need to be re-fetched
            sv = new ContactStockView();
            sv.name = (TextView) rowView.findViewById(R.id.contact_name);
            sv.number = (TextView) rowView.findViewById(R.id.contact_number);
            sv.photo = (ImageView) rowView.findViewById(R.id.contact_photo);

            // Cache the view objects in the tag,
            // so they can be re-accessed later
            rowView.setTag(sv);
        } else {
            sv = (ContactStockView) rowView.getTag();
        }
        // Transfer the stock data from the data object
        // to the view objects
        ContactStock currentStock = (ContactStock) stocks.get(position);
        sv.name.setText(currentStock.getName());
        sv.number.setText(currentStock.getNumber());
        sv.photo.setImageBitmap(currentStock.getPicture()); // NEW LINE

        // TODO Auto-generated method stub
        return rowView;
    }

    protected static class ContactStockView {
        protected TextView name;
        protected TextView number;
        protected ImageView photo; // NEW LINE
    }
}

解决方案

There are two problems in your code. The first one is easy to overcome, the others need more work.

Lets start with the easy one: The method ContactsContract.Contacts.openContactPhotoInputStream(cr, uri) takes a contact uri and not a photo uri. That is the id in your call to ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id) has to be a contact id.

Also you create a lot of Bitmap objects when iterating over the result set. Don't do this. Though this might work at first, it probably crashes with OutOfMemory errors when the list get's to long. Try to create as few Bitmapobjects as necessary. That is: Only for those rows visible. When scrolling the list view you have to recycle existing Bitmaps.

这篇关于加载一个联系人的图片变成ListView控件(部分2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆