Android 加载一个触点';将图片导入ListView(第2部分)
根据那里的答案,我已经修改了,以便将联系人的图片加载到列表视图中。我正在使用loadContactPhoto(ContentResolver cr,long id)获取Photo_id,并使用它获取联系人的位图。问题是没有ImageView获得新图像,尽管照片id总是不同的。我尝试使用联系人。\u ID,但仍然只有两个联系人的ImageView获得了联系人图片,而且他们都错了。我已经评论了我在下面添加的新行 以下是编辑后的代码: 联系股票:Android 加载一个触点';将图片导入ListView(第2部分),android,image,contactscontract,Android,Image,Contactscontract,根据那里的答案,我已经修改了,以便将联系人的图片加载到列表视图中。我正在使用loadContactPhoto(ContentResolver cr,long id)获取Photo_id,并使用它获取联系人的位图。问题是没有ImageView获得新图像,尽管照片id总是不同的。我尝试使用联系人。\u ID,但仍然只有两个联系人的ImageView获得了联系人图片,而且他们都错了。我已经评论了我在下面添加的新行 以下是编辑后的代码: 联系股票: public class 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);
}
}
代码中有两个问题。第一个很容易克服,其他的需要更多的工作 让我们从简单的一个开始: 方法
ContactsContract.Contacts.openContactPhotoInputStream(cr,uri)
获取联系人uri而不是照片uri。这是您对ContentUris的调用中的id。withAppendedId(Contacts contract.Contacts.CONTENT\u URI,id)
必须是联系人id
在迭代结果集时,还可以创建许多
位图对象。不要这样做。虽然这在一开始可能有效,但当列表变长时,它可能会因OutOfMemory
错误而崩溃。根据需要尝试创建尽可能少的位图
对象。即:仅适用于那些可见的行。当滚动列表视图时,你必须回收现有的位图。因为我在计算如何在没有任何UI冻结的情况下高效加载所有联系人的照片时遇到了很多麻烦,在我第一次开始使用Android时加载图像时出现了错误,我强烈建议任何人仔细看看我的问题
这是一个示例应用程序,教你如何处理所有处理数据和无缝加载图像,在滚动列表时有效地避免任何“打嗝”。这也是一个伟大的项目,让你开始在Android上工作
具体来说,对于my questions代码的联系人图像部分,API提供了两个简单的方法,可以找到它们返回联系人高分辨率图像或缩略图的InputStream
。您所要做的就是使用BitmapFactory.decodeByteArray()
对其进行解码。记住加载你需要在你的应用程序中使用的图像的大小(在上面的链接中描述),这样你就不会得到OutOfMemoryError
为了进一步改进代码,您还可以使用自定义光标适配器替换ArrayAdapter,并且只在现场加载所需的listView行。如何解决此问题?请阅读问题的答案。我已经写了一个自己的所有细节和例子,你需要
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
}
}