【问题标题】:Android- Loading Contacts with ViewHolder and AsyncTask- Thumbnail issueAndroid- 使用 ViewHolder 和 AsyncTask 加载联系人- 缩略图问题
【发布时间】:2013-12-09 00:03:01
【问题描述】:

我正在创建一个自定义联系人应用程序。我使用带有 ViewHolder 设计模式的 ArrayAdapter 进行优化...由于加载缩略图图片需要很长时间,我使用 AsyncTask 类加载图像,用于第一组在我的屏幕上的联系人中,图片加载良好,但是当我向下滚动时,同一组图片正在随机重新循环用于其他联系人......我已经搜索了这个论坛并找到了一些解决方案,但没有一个对我有用.我将把我的代码放在下面.. 请有人告诉我代码中有什么问题,而不是将其标记为重复的 qn...

public class CustomList extends ArrayAdapter<String>{

    private final Activity context;
    private final ArrayList<String> displayName,demoteValue,emergency;
    ArrayList<Long> contactId;

    public CustomList(Activity context,ArrayList<Long> contactId,ArrayList<String> displayName,ArrayList<String> demoteValue ,
            ArrayList<String> emergency) {
        super(context, R.layout.list_single, displayName);
        this.context = context;
        this.displayName = displayName;
        this.demoteValue = demoteValue;
        this.emergency = emergency;
        this.contactId=contactId;

    }

    class MyViewHolder
    {
        public QuickContactBadge imageView;
        public TextView txtTitle;
        int position;

        MyViewHolder(View v){
            txtTitle = (TextView) v.findViewById(R.id.txt);
            imageView = (QuickContactBadge) v.findViewById(R.id.contactimageentry);
        }
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView=convertView;
        MyViewHolder holder=null;

        if(rowView==null)
        {
             LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             rowView = inflater.inflate(R.layout.list_single, parent, false);
             holder=new MyViewHolder(rowView);
             rowView.setTag(holder);

        }else{
            holder= (MyViewHolder) rowView.getTag();
        }

        holder.txtTitle.setText(displayName.get(position));
        holder.txtTitle.setPadding(5, 5, 5, 5);
        //Some BLA BLA BLA work.
        if(emergency.get(position).equals("1")){

            holder.txtTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP,25);
            holder.imageView.getLayoutParams().width=getPixels(TypedValue.COMPLEX_UNIT_DIP,50);

}            
        //Get and set the photo-HERE LIES THE CALL TO THE PROBLEM
        holder.position = position;
        new LoadContactImage(getContext(),holder,position,contactId.get(position))
        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);       
        return rowView;
    }   
}

这是我的异步任务的代码,它根据我在调用它时传递的 ID 加载图像

public class LoadContactImage extends AsyncTask<Object, Void, Bitmap> {

private long Path;
private MyViewHolder mHolder;
private int mposition;
Context ctx;

public LoadContactImage(Context context,MyViewHolder holder,int position,Long id) {
    this.mHolder= holder;
    this.Path = id;
    this.mposition=position;
    this.ctx= context;
}

@Override
protected Bitmap doInBackground(Object... params) {
    Uri my_uri = getPhotoUri(Path);
    ContentResolver cr = ctx.getContentResolver();
    InputStream in = null;
    try {
        in = cr.openInputStream(my_uri);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Bitmap bitmap = BitmapFactory.decodeStream(in);
    return bitmap;
}

@Override
protected void onPostExecute(Bitmap result) {

    super.onPostExecute(result);
    if (result != null && mposition == mHolder.position) {
        //imv.setImageBitmap(result);
        mHolder.imageView.setImageBitmap(result);
    }
}   
}

【问题讨论】:

  • 我在这里没有发现问题。当您第一次在 getView 方法中创建持有人时,您可能应该调用 holder.imageView.setImageBitmap 到原来的任何内容。否则,在加载完成之前,图像仍然具有旧值。
  • 谢谢或你的回应......但我真的不明白你的改变..你能说明一下或突出显示应该改变的代码吗?
  • 在开始加载 AsyncTask 之前的行中,您应该设置 holder.imageView.setImageBitmap(loadingImage) 否则旧图像仍会显示,因为 ListView 回收其视图 - 滚动出的视图在顶部被重新插入底部(和其他方式)。
  • 所以你的意思是我必须将在 onPostExecute(Bitmap result) 中找到的结果返回到 getView() 并使用 holder.imageView.setImageBitmap(returnedImage); 将图像设置在那里??
  • 不 - 你只需要在获取视图方法中将图像设置回某个初始状态,然后再开始后台加载

标签: android design-patterns android-asynctask thumbnails android-contacts


【解决方案1】:

想通了......现在它的工作..Simon Meyer 在评论中给出的Soln 是正确的..我需要在 getView() 中将 imageView 初始化为位图,然后才能调用 Async Task..这是更改在代码中

holder.position = position;

holder.imageView.setImageURI( Uri.parse("android.resource://com.vishnu.demotingprototype/drawable/ic_contact_picture"));

new LoadContactImage(getContext(),holder,position,contactId.get(position)).execute();

【讨论】:

    【解决方案2】:

    我认为您的自定义类没有找出梯形图类的上下文。 首先在 yorr 活动中声明上下文。一切都很顺利,而不是这个......它工作正常

    【讨论】:

    • 但是先生,这两个类都不在我的活动中..我已将它们作为单独的类...所以 getContext() 不起作用,这就是为什么我将上下文作为参数传递给 Async类...你的意思是它的问题?如果是的话如何获取上下文?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多