在列表视图性能中加载联系人照片
我想在 ListView 中显示联系人的照片。当有大量联系人时,我面临性能问题(滚动不流畅)。我正在使用 ArrayAdapter 的 getView 方法将联系人照片分配给 ImageView。当不使用图像时,滚动是平滑的。
但默认的联系人应用滚动非常流畅。所以我的应用程序存在性能问题。
我怎样才能提高性能?请建议。
private class MyArrayListAdapter extends ArrayAdapter<ContactsBook> implements OnItemClickListener{
private ArrayList<ContactsBook> mContacts;
private Context mContext;
public MyArrayListAdapter(Context context, int textViewResourceId, ArrayList<ContactsBook> contacts) {
super(context, textViewResourceId, contacts);
mContacts= contacts;
mContext=context;
}
@Override
public View getView(int position, View converview, ViewGroup parent){
View view=converview;
ViewHolder viewHolder=new ViewHolder();
if(view==null){
LayoutInflater inflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view=inflater.inflate(R.layout.phone_row, null);
viewHolder.tvName=(TextView)view.findViewById(R.id.tvContact);
viewHolder.tvPhoneNo=(TextView)view.findViewById(R.id.tvPhoneNo);
viewHolder.qcBadge=(QuickContactBadge)view.findViewById(R.id.qContact);
view.setTag(viewHolder);
}
else
viewHolder=(ViewHolder) view.getTag();
ContactsBook cb=mContacts.get(position);
if(cb!=null){
Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,cb.getContactIndex());
BitmapDownloaderTask bdTask=new BitmapDownloaderTask(viewHolder.qcBadge);
bdTask.execute(contactPhotoUri.toString());
viewHolder.qcBadge.assignContactUri(contactPhotoUri);
viewHolder.qcBadge.setImageBitmap(framePhoto(BitmapFactory.decodeResource(getResources(), R.drawable.ic_contact_list_picture)));
viewHolder.tvName.setText(getContactDisplayName(cb.getContactIndex()));
viewHolder.tvPhoneNo.setText(getContactPhoneNo(cb.getContactIndex()));
}
return view;
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
/**
* Actual download method.
*/
@Override
protected Bitmap doInBackground(String... params) {
url = params[0];
Uri conUri=Uri.parse(url);
InputStream photoInputStream=Contacts.openContactPhotoInputStream(mContext.getContentResolver(), conUri);
if(photoInputStream==null)
return framePhoto(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_contact_list_picture));
Bitmap photo=framePhoto(getPhoto(mContext.getContentResolver(), conUri));
return photo;
}
/**
* Once the image is downloaded, associates it to the imageView
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
imageView.setImageBitmap(bitmap);
}
}
}
I want to display contact's photo in a ListView. I am facing performance problem(Scrolling is not smooth) when there is a large number of contacts. I am using ArrayAdapter's getView method to assign contact photo to ImageView. When image is not used then scrolling is smooth.
But the default contact application scrolling is very smooth. So there is a performance problem in my application.
How can I improve the performance? Please suggest.
private class MyArrayListAdapter extends ArrayAdapter<ContactsBook> implements OnItemClickListener{
private ArrayList<ContactsBook> mContacts;
private Context mContext;
public MyArrayListAdapter(Context context, int textViewResourceId, ArrayList<ContactsBook> contacts) {
super(context, textViewResourceId, contacts);
mContacts= contacts;
mContext=context;
}
@Override
public View getView(int position, View converview, ViewGroup parent){
View view=converview;
ViewHolder viewHolder=new ViewHolder();
if(view==null){
LayoutInflater inflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view=inflater.inflate(R.layout.phone_row, null);
viewHolder.tvName=(TextView)view.findViewById(R.id.tvContact);
viewHolder.tvPhoneNo=(TextView)view.findViewById(R.id.tvPhoneNo);
viewHolder.qcBadge=(QuickContactBadge)view.findViewById(R.id.qContact);
view.setTag(viewHolder);
}
else
viewHolder=(ViewHolder) view.getTag();
ContactsBook cb=mContacts.get(position);
if(cb!=null){
Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,cb.getContactIndex());
BitmapDownloaderTask bdTask=new BitmapDownloaderTask(viewHolder.qcBadge);
bdTask.execute(contactPhotoUri.toString());
viewHolder.qcBadge.assignContactUri(contactPhotoUri);
viewHolder.qcBadge.setImageBitmap(framePhoto(BitmapFactory.decodeResource(getResources(), R.drawable.ic_contact_list_picture)));
viewHolder.tvName.setText(getContactDisplayName(cb.getContactIndex()));
viewHolder.tvPhoneNo.setText(getContactPhoneNo(cb.getContactIndex()));
}
return view;
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
/**
* Actual download method.
*/
@Override
protected Bitmap doInBackground(String... params) {
url = params[0];
Uri conUri=Uri.parse(url);
InputStream photoInputStream=Contacts.openContactPhotoInputStream(mContext.getContentResolver(), conUri);
if(photoInputStream==null)
return framePhoto(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_contact_list_picture));
Bitmap photo=framePhoto(getPhoto(mContext.getContentResolver(), conUri));
return photo;
}
/**
* Once the image is downloaded, associates it to the imageView
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
imageView.setImageBitmap(bitmap);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
getView()
中创建视图时,您应该放置一个通用图标来代替照片,然后启动 AsyncTask 在后台加载图像并从getView()
返回尽可能快。然后,当图像准备好时(AsyncTask 后台任务完成),您可以将视图中的通用图标替换为加载的图像。这样图像可能不会立即显示,但滚动会很流畅。
When creating a view in
getView()
you should place a generic icon in place of photo, then start an AsyncTask to load the image in the background and return fromgetView()
as fast as possible. Then when image is ready (AsyncTask background task is done) you replace the generic icon in the view with the loaded image.This way images might not show immediately, but the scrolling will be smooth.