4

Я использую ListView, содержащий изображения. Эти изображения загружаются из Интернета внутри адаптера. Поэтому я использую UniversalImageDownloader.Прокрутка ListView с использованием UniversalImageDownloader негладкая

К сожалению, прокрутка ListView «отстает» на короткое время, как только я прокручу вниз, где нужно загрузить новый контент.

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

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

Возможно, параметры моего ImageLoader установлены неправильно?

Я что-то не так в моем адаптере?

элемент управления ListView содержит около 20-30 изображений с размерами 640x320 (около 150 КБ)

Ниже вы можете увидеть мой адаптер, а также ImageLoader. (Класс Downloader это просто класс обертка для UniversalImageDownloader)

public class Downloader { 

    /** 
    * initializes the imagedownloader with a specific configuration 
    * I CALL THIS METHOD RIGHT AFTER APP STARTUP 
    * @param c 
    */ 
    public static void initialize(Context c) { 

     // Create global configuration and initialize ImageLoader with this configuration 

     ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(c) 
     .threadPoolSize(20) 
     .threadPriority(Thread.NORM_PRIORITY) // default 
     .tasksProcessingOrder(QueueProcessingType.FIFO) // default 
     .memoryCacheSize(20 * 1024 * 1024) 
     .memoryCacheSizePercentage(15) // default 
     .discCacheSize(20 * 1024 * 1024) 
     .discCacheFileCount(100) 
     .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default 
     .imageDecoder(new BaseImageDecoder()) // default 
     .build(); 

     ImageLoader.getInstance().init(config); 
    } 

    /** 
    * gets the display options that are needed when displaying an image 
    * @return 
    */ 
    public static DisplayImageOptions getDisplayOptions() { 

     DisplayImageOptions options = new DisplayImageOptions.Builder() 
     .showImageForEmptyUri(R.drawable.error) 
     .showImageOnFail(R.drawable.error) 
     .resetViewBeforeLoading(false) // default 
     .cacheInMemory(true) // default 
     .cacheOnDisc(true) // default 
     .build(); 

     return options; 
    } 

    public static ImageLoader getInstance() { 
     return ImageLoader.getInstance(); 
    } 
} 

И адаптер:

public class EventListAdapter extends ArrayAdapter<Event> { 

    private List<Event> mList; 
    private DisplayImageOptions options; 

    public EventListAdapter(Context context, int list_item_resource, List<Event> objects) { 
     super(context, list_item_resource, objects); 
     mList = objects; 

     options = Downloader.getDisplayOptions(); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     Event event = mList.get(position); 

     // A ViewHolder keeps references to children views to avoid unneccessary calls to findViewById() on each row. 
     ViewHolder holder = null; 

     if (convertView == null) { 

      LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.normalevent_list_item, parent, false); 

      holder = new ViewHolder();; 

      holder.eventimage = (ImageView) convertView.findViewById(R.id.ivEventImage); 

      convertView.setTag(holder); 

     } else { 
      holder = (ViewHolder) convertView.getTag(); 

     } 

     if (event != null) { 

      holder.eventimage.setImageResource(R.drawable.loading); 
      // Load image, decode it to Bitmap and display Bitmap in ImageView 
      Downloader.getInstance().displayImage(event.getImageOneURL(), holder.eventimage, options); 
     } 

     return convertView; 
    } 

    private static class ViewHolder { 

     ImageView eventimage; 
    } 
} 

ответ

8

Я была такая же проблема с загрузкой изображений. Я решил это, установив delayBeforeLoading (1000) в свой DisplayImageOptions. Необходимо начать загрузку, когда пользователь перестанет бросать.

поэтому попробуйте заменить метод getDisplayOptions с этим

public static DisplayImageOptions getDisplayOptions() { 

    DisplayImageOptions options = new DisplayImageOptions.Builder() 
    .showImageForEmptyUri(R.drawable.error) 
    .showImageOnFail(R.drawable.error) 
    .delayBeforeLoading(1000) 
    .resetViewBeforeLoading(false) // default 
    .cacheInMemory(true) // default 
    .cacheOnDisc(true) // default 
    .build(); 

    return options; 
} 

Документация также рекомендует использовать этот код, чтобы избежать просмотра сетки/список прокрутки запаздывает

boolean pauseOnScroll = false; // or true 
boolean pauseOnFling = true; // or false 
PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling); 
listView.setOnScrollListener(listener); 

Вы можете прочитать его here (последний пункт «Полезная информация»)

Таким образом, вы можете использовать один из этих методов

+0

И лаги ушли, спасибо вам большое! :) PS: Я установил его на 100 мс –

+0

Что такое ImageLoader в PauseOnScrollListener Constructor? – AndroSco

1

@Sergey Pekar: Ты спас мне жизнь! :) Я всегда использовал UIL для ListView для небольшого количества изображений, но затем по мере увеличения числа я всегда получал задержку при первой загрузке (при прокрутке) изображений. Итак, я также пробовал задержку, и это помогло немного и другим настройкам и настройкам UIL, но я не был доволен. Затем я пробовал разные библиотеки загрузки изображений (Picasso, AQuery, Volley, UrlImageViewHelper, настраиваемый код). Все они работали быстрее (при первой загрузке), чем UIL, но у них не было достаточно вариантов для меня. Итак, я искал последние 2 дня для решения этой проблемы с запаздыванием и богом-ях, я наконец нашел ваше сообщение здесь! Решение было PauseOnScrollListener!

Что также (Addtionally к PauseOnScrollListener) улучшает немного свитка-плавности путем расширения ImageView, чтобы остановить requestLayout как это:

public class CustomImageView extends ImageView 
{ 
    public CustomImageView (Context context, AttributeSet attributeset, int int_style) 
    { 
     super(context, attributeset, int_style); 
    } 

    public CustomImageView (Context context, AttributeSet attributeset) 
    { 
     super(context, attributeset); 
    } 

    public CustomImageView (Context context) 
    { 
     super(context); 
    } 

    @Override 
    public void requestLayout() 
    { 
     // Do nothing here 
    } 
} 

Для получения дополнительной информации см этот пост:
ListView very slow when scrolling (using ViewHolder/recycling)

+1

ты спас мне жизнь! Это была неделя. Я попробовал все доступные библиотеки (более 10). Но мой список был очень вялым, когда он бросался. Я также попытался с PauseOnScrollListener из UIL. Но ваш CustomImageView сделал трюк. Теперь мой список работает так же быстро, как Wind :) –

+0

Так что я использовал ту же самую комбо. UIL с этим CustomImageView –

+0

Приятно слышать Seshu :) – DroidFox