Android- загрузка контактов с помощью ViewHolder и AsyncTask- проблема с миниатюрами

Я создаю пользовательское приложение для контактов. Я использую ArrayAdapter с шаблоном дизайна ViewHolder для оптимизации... Так как загрузка пиктограмм заняла много времени, я использую класс 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;
    }   
}

А вот код для моей асинхронной задачи, которая загружает изображения на основе идентификатора, который я передал во время вызова

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);
    }
}   
}

2 ответа

Решение

Разобрался... Теперь он работает. Солн, данный Саймоном Мейером в комментариях, правильный. Мне нужно инициализировать imageView для растрового изображения в getView(), прежде чем я смогу вызвать 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();

Я думаю, что ваш пользовательский класс не узнать контекст класса изображения Ладера. Сначала объявляйте контекст в деятельности yorr. Все идет хорошо, а не это.... Работает нормально

Другие вопросы по тегам