2015-02-06 4 views
2

Это очень большая проблема для меня, я много часов работал над этим и не знал!У вас возникли проблемы с загрузкой асинхронного изображения в ListView

У меня проблема с загрузкой асинхронного изображения в ListView.

Я использую Parse.com в качестве бэкэда моего приложения, я получаю сообщения и их изображения из класса Parse.com.

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

Я думаю, что это происходит потому, что я использую класс, как это Загрузка изображений

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> 

В любом случае мой класс адаптера является следующее:

public class adapterview extends ArrayAdapter<Message> { 
Bitmap image; 
public adapterview(Context context, ArrayList<Message> Messages) { 
    super(context, 0, Messages); 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // Get the data item for this position 
    final Message m = getItem(position);  
    // Check if an existing view is being reused, otherwise inflate the view 
    if (convertView == null) { 
     convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom2, parent, false); 
    } 

    TextView message = (TextView) convertView.findViewById(R.id.message); 
    TextView date = (TextView) convertView.findViewById(R.id.date); 
    TextView user = (TextView) convertView.findViewById(R.id.user); 
    message.setText(m.getMessage()); 
    user.setText(m.getUser()); 
    new DownloadImageTask((ImageView) convertView.findViewById(R.id.imageView1)) 
    .execute(m.getImage()); 

    return convertView; 


} 


private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 
    ImageView bmImage; 

    public DownloadImageTask(ImageView bmImage) { 
     this.bmImage = bmImage; 
    } 

    protected Bitmap doInBackground(String... urls) { 
     String urldisplay = urls[0]; 
     Bitmap mIcon11 = null; 
     try { 
     InputStream in = new java.net.URL(urldisplay).openStream(); 
     mIcon11 = BitmapFactory.decodeStream(in); 
     } catch (Exception e) { 
      Log.e("Error", e.getMessage()); 
      e.printStackTrace(); 
     } 
     return mIcon11; 
    } 

    protected void onPostExecute(Bitmap result) { 
     bmImage.setImageBitmap(result); 
    } 
} 

и это мой класс сообщений:

public class Message { 

String message; 
String user; 
String phone; 
String image; 
String date; 

public String getDate() { 
    return date; 
} 

public void setDate(String date) { 
    this.date = date; 
} 

public String getImage() { 
    return image; 
} 

public void setImage(String image) { 
    this.image = image; 
} 

public String getPhone() { 
    return phone; 
} 

public void setPhone(String phone) { 
    this.phone = phone; 
} 

public String getUser() { 
    return user; 
} 

public void setUser(String user) { 
    this.user = user; 
} 

public String getMessage() { 
    return message; 
} 

public void setMessage(String message) { 
    this.message = message; 
} 
} 

и вот как я добавляю товары в свой список:

contacts c = new contacts(); 
      c.setName(object.get("name").toString()); 
      c.setNumero(object.get("phone").toString()); 
      ParseFile image = (ParseFile)object.get("Profil"); 
      c.setProfil(image.getUrl()); 
      messagelist.addcontact(c); 

и это код, как я заполняю вид списка из MainActivity:

 adapterview adapter = new adapterview(MainActivity.this, (ArrayList<Message>) messagelist); 
    list.setAdapter(adapter); 

Вот две картинки, когда я прокручиваю вниз, а затем вверх, чтобы изображение первых изменений ListItem! ! без каких-либо причин, а затем через несколько секунд вернитесь к нормальной картине.

enter image description here

enter image description here

Если вы можете предложить новый способ, как я могу загрузить изображения из URL в ImageView, что было бы здорово.

ответ

2

То, что вы наблюдаете это я думаю, что из-за шаблон viewholder в listview.You пытается загружать и устанавливать изображение на изображения через aysnctask в getview(), но когда вы прокручиваете или опускаете представление, перерабатывайте, и когда вы снова переходите в эту позицию, ваш getview вызывается для этой позиции, так что асинтеза снова выполняется и загружает установленный образ в образе просмотра снова, поэтому вы видите задержку, я предлагаю вам использовать PICASSO libraray от площади она является достаточно эффективной для загрузки изображений и кэширует изображения также здесь ссылка http://square.github.io/picasso/ или использовать Glide, который теперь официально рекомендован Google, вот ссылка Glide

+0

Спасибо, это решило мою проблему :) –

+0

@NadadorBase Base рада помочь –

1

В прошлый раз я также использовал ручную загрузку аватаров контактов, но это плохо. Ваша проблема, я думаю:

  • Скачать аватар, а затем установить в ImageView
  • Но, вы используете ViewHolder шаблон, так что новый скаченный аватар будет установлен на многих ImageView> неверном аватар для указанного контакта (это только хорошо работать когда загружаются все аватары)

Прежде всего, отметьте библиотеку Universal Image Loader, установите URL-адрес аватара для просмотра, и он будет автоматически загружаться, кэшировать ваши аватары в память.

После этого отправьте сюда, если у вас по-прежнему возникает проблема с аватаром.

+0

Не могли бы вы дать более подробную информацию о том, как я могу сделать то, что вы сказали?вы можете дать учебник, и любой источник –

0

Что представляет собой XML-файл раскладки ячейки списка? Я думаю, что Android не может определить размер ячейки списка. Это вызывает некоторые проблемы. Если вы хотите использовать async для загрузки изображений, одним из способов избежать проблемы является исправление размера изображения.Например

<ImageView 
     android:id="@+id/row_icon1" 
     android:layout_width="60dip" 
     android:layout_height="60dip" 
     android:layout_gravity="center_vertical" 
    /> 
+0

Я уже сделал это, это работает хорошо –

1

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

Это странное поведение происходит из-за AsyncTask в getView методом без Просмотр шаблона владельца.

Чтобы избежать рендеринга уже сделанных эскизов изображений и загрузки новых изображений из сети в виде списка, используйте прокрутку.

Смотрите следующий полезный учебник для создания ListView с хорошей прокруткой и загрузкой Performace с помощью View Holder:

Performance Tips for Android’s ListView

1

GitHub Это происходит потому, что ListView Переработайте при прокрутке, а затем, когда вы вызываете свою задачу асинхронизации для загрузки изображений и прокрутки, завершение загрузки, но ссылка указывает на переработанное представление и одну или несколько задач async, указывающих на один и тот же вид. Один из способов избежать этого - его отметка, которую вы просматриваете при запуске загрузки, и когда вы заканчиваете загрузку, прежде чем нарисовать изображение, проверьте правильность его ссылки и затем нарисуйте изображение.

Вы можете пометить представление URL-адресом изображения, поскольку его уникальное значение.

В предварительном порядке загрузки вы должны пометить ImageView с помощью URL (String).

imageView.setTag(url); 

И когда задача закончена и перед тем, как нарисовать изображение, восстановите его и проверьте его.

String tag = (String)imageView.getTag(); 
if(tag != null && tag.equals(url)){ 
    //Draw the image 
} else { 
    //Draw the placeholder or clean the ImageView 
} 

И вы можете обновить производительность из вас ListView с помощью шаблона ViewHolder, и почему вы загружаете изображение вручную, когда Анализировать может выполнить это их API, для способа анализа и с помощью политики кэша, при загрузке изображение автоматически кэширует растровое изображение, и когда вы снова запрашиваете загрузку, просто извлекаете полученный результат.

Cheers!

1

Я решил с помощью зрения рецикла в onBindViewHolder

@Override 
public void onBindViewHolder(final MyViewHolder viewHolder, int i) { 
    CartsViewModel currentData = data.get(i); 
    ParseFile image = currentData.getParseImage(); 
    if(image!=null){ 
     Log.d(TAG,"image not null. Downloading...."); 
     image.getDataInBackground(new GetDataCallback() { 
      @Override 
      public void done(byte[] bytes, ParseException e) { 
       if(e==null){ 
        Log.d(TAG,"donload finished"); 
        Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
        viewHolder.cartImage.setImageBitmap(bmp); 
       }else{ 
        viewHolder.cartImage.setImageBitmap(null); 
       } 
      }else{ 
       viewHolder.cartImage.setImageBitmap(null); 
      } 
     }); 
    } 
    viewHolder.cartName.setText(currentData.getCartName()); 
    viewHolder.cartAddress.setText(currentData.getCartAddress()); 
    viewHolder.rating.setText(currentData.getRating()); 
    viewHolder.reviewCount.setText(currentData.getReviewCount()); 

} 

работает как шарм с методом разбора.

+0

Я решил вызвать 'viewHolder.cartImage.setImageBitmap (null); 'перед загрузкой – jose920405

Смежные вопросы