6

В моем проекте Android я показываю все изображения от web service(Url) до ListView для этой цели. Я использовал Universal image loader. После загрузки некоторых изображений в List, если я прокручиваю вниз, прокручиваем Up, уже загруженные изображения снова загружаются.Listview перезагружает уже загруженные изображения с помощью универсального загрузчика изображений

DisplayImageOptions.Builder displayImageOptionsBuilder = new DisplayImageOptions 
        .Builder().cacheOnDisk(true).cacheInMemory(true).considerExifParams(true); 


ImageLoader.getInstance().displayImage(imageUri, imageView, 
        displayImageOptionsBuilder.build()); 

То, что я пытался

ImageAware imageAware = new ImageViewAware(imageView, false); 
      ImageLoader.getInstance().displayImage(imageUri, imageAware,displayImageOptionsBuilder.build()); 

Даже использовал этот код не будет вносить какие-либо изменения в ListView reloading

Edited

адаптер класса

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     final String name = getItem(position); 
     View view = convertView;  

     if (view == null) { 
      view = createView(); 
      ViewHolder viewHolder = new ViewHolder();  
      viewHolder.image = (ImageView) view.findViewById(R.id.capsule_media_list_item_thumbnail_1);    
      view.setTag(viewHolder);  
     } 

ImageHelper.initImage(viewHolder.image, 
       imageUrl, 
       R.drawable.vx_loading, loadingImageResource,displayOptionsCustomizer); 

return view; 
} 

private final DisplayOptionsCustomizer displayOptionsCustomizer = new DisplayOptionsCustomizer() { 

     @Override 
     public void customizeImageOptions(DisplayImageOptions.Builder displayImageOptionsBuilder) { 
      displayImageOptionsBuilder.displayer(new RoundedBitmapDisplayer(ApplicationUtils 
        .dipToPixelsRounded(6, getContext()), 0)); 
     } 
    };  

static class ViewHolder { 
     public ImageView image; 

    } 

ImageHelper.java

public static void initImage(final ImageView imageView, final String imageUri, 
           final int noImageResource, final int loadingImageResource, 
           final DisplayOptionsCustomizer displayOptionsCustomizer) { 
     if (StringUtils.isNotBlank(imageUri)) {    

      DisplayImageOptions.Builder displayImageOptionsBuilder = new DisplayImageOptions 
        .Builder().cacheOnDisk(true).cacheInMemory(true).considerExifParams(true); 
      displayImageOptionsBuilder.showImageOnLoading(loadingImageResource) 
        .showImageOnFail(noImageResource); 
      if (displayOptionsCustomizer != null) { 
       displayOptionsCustomizer.customizeImageOptions(displayImageOptionsBuilder); 
      } 


      ImageLoader.getInstance().displayImage(imageUri, imageView, 
        displayImageOptionsBuilder.build()); 
     } else { 
      if (noImageResource != 0) { 
       imageView.setImageResource(noImageResource); 
      } else { 
       imageView.setVisibility(View.GONE); 
      } 
     } 
    } 

Edited адаптер класса согласно Dhir Pratapответ

public class ImagesListAdapter extends ArrayAdapter<String> { 

private List imagesList = new ArrayList<String>(); 
private Context context; 
ImageLoader imageLoader; 
DisplayImageOptions options; 

public ImagesListAdapter(Context context, List<String> imagesList) { 
     super(context, -1,imagesList); 
     this.imagesList = imagesList; 
     this.context = context; 
imageLoader = ImageLoader.getInstance(); 
options = new DisplayImageOptions.Builder().cacheInMemory(true) 
     .cacheOnDisk(true).resetViewBeforeLoading(true) 
     .showImageForEmptyUri(fallbackImage) 
     .showImageOnFail(fallbackImage) 
     .showImageOnLoading(fallbackImage).build(); 

    }  

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     final String name = getItem(position); 
     View view = convertView;  
ViewHolder viewHolder; 

     if (view == null) { 
      view = createView(); 
      viewHolder = new ViewHolder();  
      viewHolder.image = (ImageView) view.findViewById(R.id.capsule_media_list_item_thumbnail_1);    
      view.setTag(viewHolder);  
     } 
else{ 

viewHolder = (ViewHolder) view.getTag(viewHolder); 
} 

/*ImageHelper.initImage(viewHolder.image, 
       imageUrl, 
      R.drawable.vx_loading, loadingImageResource,displayOptionsCustomizer);*/ 

imageLoader.displayImage(imageUrl,viewHolder.image, 
      options); 

return view; 
} 

/* private final DisplayOptionsCustomizer displayOptionsCustomizer = new DisplayOptionsCustomizer() { 

     @Override 
     public void customizeImageOptions(DisplayImageOptions.Builder displayImageOptionsBuilder) { 
      displayImageOptionsBuilder.displayer(new RoundedBitmapDisplayer(ApplicationUtils 
        .dipToPixelsRounded(6, getContext()), 0)); 
     } 
    }; */ 

static class ViewHolder { 
     public ImageView image; 

    } 

} 
+0

ваш вопрос непонятен ... как вы использовали ImageLoader в getView адаптера? Насколько велики изображения (важно, поскольку загрузчики изображений могут выпускать кешированные растровые изображения, когда память низкая, поэтому она должна загружать ее из дискового кеша или даже из Интернета (см. Следующий вопрос))? Также использует ли сервер e-tag (или другие заголовки кеширования)? – Selvin

+0

@Selvin Я тоже редактировал свой вопрос с помощью метода getView() класса адаптера. – Jamal

+0

Размеры изображения различаются, каждое изображение имеет собственный размер. Они, вероятно, 14,1 кб, 13,2 кб, 27 кб, 23,4 кб, 11 кб и т. Д. – Jamal

ответ

12

Есть несколько исправлений вы можете сделать

  1. Ваш владелец выглядит почти бесполезным. Вы должны использовать его как следовать

    ViewHolder viewHolder; 
    if (view == null) { 
        viewHolder = new ViewHolder();  
        viewHolder.image = (ImageView) view.findViewById(R.id.capsule_media_list_item_thumbnail_1);    
        view.setTag(viewHolder);  
    }else{ 
    viewHolder = view.getTag(viewHolder); 
    } 
    
  2. Вы должны объявить экземпляр ImageLoader и DisplayImageOptions только один раз. Возможно, в конструкторе.

    ImageLoader imageLoader = ImageLoader.getInstance(); 
    DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true) 
         .cacheOnDisc(true).resetViewBeforeLoading(true) 
         .showImageForEmptyUri(fallbackImage) 
         .showImageOnFail(fallbackImage) 
         .showImageOnLoading(fallbackImage).build(); 
    
  3. По мнению ПОЛУЧИТЬ вы просто загрузить изображение следовать

Edit: я не использовал ImageAware. Вы должны использовать это.

ImageAware imageAware = new ImageViewAware(viewHolder.image, false); 
imageLoader.displayImage(imageUri, imageAware,options); 

The answer здесь говорит, что это действительно была проблема с ИЮОЖА которая была исправлена ​​в версии 1.9.

Edit 2: Я последовал за обсуждение этого вопроса на Github и нашел this answer, который делает ручную проверку на URL изображения. Предлагается сделать следующее:

//lets prevent "blinking" by "saving URL tag" hack 

    if (viewHolder.image.getTag() == null || 
      !viewHolder.image.getTag().equals(imageUri)) { 

     //we only load image if prev. URL and current URL do not match, or tag is null 

     ImageAware imageAware = new ImageViewAware(viewHolder.image, false); 
     imageLoader.displayImage(imageUri, imageAware,options); 
     viewHolder.image.setTag(imageUri); 
    } 
+1

Dhir Pratap, я пробовал ваш код, но все-таки эта проблема возникает. 'cacheOnDisc (true)' метод 'устаревший', поэтому я попытался с' cacheOnDisk (true) 'слишком – Jamal

+0

Можете ли вы обновить вопрос с изменениями, я могу посмотреть дальше. –

+0

Я обновил свой класс «Адаптер» – Jamal

0

У меня такая же проблема. Помещение файла ApplicationClass.java в папку src и регистрация его в файл манифеста решит вашу проблему.

вот двух файлов:

ApplicationClass.Java

package yourPackageName; 

import android.app.Application; 

import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache; 
import com.nostra13.universalimageloader.core.DisplayImageOptions; 
import com.nostra13.universalimageloader.core.ImageLoader; 
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 
import com.nostra13.universalimageloader.core.assist.ImageScaleType; 
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; 

public class ApplicationClass extends Application 
{ 
    @Override 
    public void onCreate() { 
     super.onCreate(); 

     // UNIVERSAL IMAGE LOADER SETUP 
     DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder().cacheOnDisc(true).cacheInMemory(true) 
       .imageScaleType(ImageScaleType.EXACTLY).displayer(new FadeInBitmapDisplayer(300)).build(); 

     ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) 
       .defaultDisplayImageOptions(defaultOptions).memoryCache(new WeakMemoryCache()) 
       .discCacheSize(100 * 1024 * 1024).build(); 

     ImageLoader.getInstance().init(config); 
     // END - UNIVERSAL IMAGE LOADER SETUP 
    } 
} 

файл манифест:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="yourPackageName"> 

    <!--Permissions --> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <application 
    android:name="com.webcluesinfotech.loadimagefromurlinlistview.ApplicationClass" 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:theme="@style/AppTheme.NoActionBar"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

Надеется, что это поможет.