Загрузка данных в ListView через AsyncTask

Ответить
JesusD
Сообщения: 2
Зарегистрирован: 05 мар 2014, 20:27

Загрузка данных в ListView через AsyncTask

Сообщение JesusD » 05 мар 2014, 21:26

Приветствую форумчане, столкнулся с некоторой проблемой, поиски по которой привели меня в тупик.
Создаю собственный Adapter для связи с ListView, но так как изображения большого размера решил загрузить их в отдельном потоке

Код: Выделить всё

 
public class MyAdapter extends ArrayAdapter<String>
{
     private final Context context;
     private final String[] values;
     private final int[] imgid;
     LayoutInflater inflater;
     public MyAdapter(Context context, String[] values, int[] val2) 
     {
        super(context, R.layout.rowlayout, values);
        this.context = context;
        this.values = values;
        this.imgid = val2;
        inflater = ((Activity)context).getLayoutInflater();
     }
	    
    static class ViewHolder 
    {
        public ImageView imageView;
        public TextView textView;
        public int imageId;
    }
	    
    public View getView(final int position, View convertView, ViewGroup parent) 
    {                       
         ViewHolder holder = null;
         if (convertView == null) 
         {
	     convertView = inflater.inflate(R.layout.rowlayout, null);
	     holder = new ViewHolder();
	     holder.textView = (TextView) convertView.findViewById(R.id.ac_s_item_1_tv_1);
	     holder.imageView = (ImageView) convertView.findViewById(R.id.ac_s_item_1_iv_1);
	     holder.position = position;
	     holder.imageId = imgid[position];
	     convertView.setTag(holder);
          }
          else 
          {
                 holder = (ViewHolder) convertView.getTag();
          }
          holder.textView.setText(values[position]);
         
          new AsyncTask<ViewHolder, Void, Bitmap>()
          {
          	     ViewHolder v;    	
	     @Override
	     protected void onPostExecute(Bitmap result) 
	     {
	     	if (v.position == position)
	       	{
	        	           super.onPostExecute(result);
	            	v.imageView.setImageBitmap(result);
	            }
        }
	        	   
	    @Override
	    protected Bitmap doInBackground(ViewHolder... parameter) 
	    {
	           v = parameter[0];
	           Bitmap bm = BitmapFactory.decodeResource(context.getResources(), v.imageId);
	        	return bm;
	     }
      }.execute(holder);
			 
    return convertView;
    }
 }
При запуске приложения, первые элементы ListView отображаются корректно, но при прокрутке изображения начинают дублироваться, то есть первый элемент который был скрыт, имеет то же изображение что и первый элемент ListView. Надеюсь я доходчиво объяснил проблему.
Во входных параметрах адаптера массив строк и массив идентификаторов изображений.
Надеюсь на вашу помощь

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Загрузка данных в ListView через AsyncTask

Сообщение rezak90 » 05 мар 2014, 21:42

Нужно реализовать Lazy Adapter.
R.id.team
Политика на форуме запрещена

JesusD
Сообщения: 2
Зарегистрирован: 05 мар 2014, 20:27

Re: Загрузка данных в ListView через AsyncTask

Сообщение JesusD » 05 мар 2014, 22:02

В чем суть? Можно материал какой нибудь? То что выдает мне гугл, не особо отвечает на мой вопрос

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Загрузка данных в ListView через AsyncTask

Сообщение rezak90 » 05 мар 2014, 22:14

Он ещё как отвечает на ваш вопрос, дело в том что асинхронный поток не успевает отработать в тот момент как view уже отображается. И по этому отображается не та картинка которая нужна. Еще как вариант можно заиспользовать библиотеку Volley, в ней есть реализация ленивого адаптера.
R.id.team
Политика на форуме запрещена

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Загрузка данных в ListView через AsyncTask

Сообщение KamiSempai » 06 мар 2014, 23:29

Как вариант, можно делать imageView невидимым в onPreExecute и видимым в onPostExecute.
И холдер лучше не через параметр передавать, в конструктор AsyncTask так как в другом потоке ему все равно делать нечего.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Ответить