Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
#1

После вызова notifydataset() items в listview "моргают" - Программирование Android

30.09.2013, 04:11. Просмотров 1676. Ответов 30
Метки нет (Все метки)

столкнулся с такой проблемой, перерыл stackoverflow, ответа не нашел
есть список listview, который показывает картинки, загружая их из сети/кэша.
для него адаптер у которого есть функция getView()
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder vh;
        ImageView imageView;
        Image image = (Image)getItem(i);
        if (view==null)
        {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.item, null);
            vh = new ViewHolder();
            vh.imageView = (ImageView) view.findViewById(R.id.imageView);
            view.setTag(vh);
        }
        vh = (ViewHolder)view.getTag();
        vh.i = i;
        imageView = vh.imageView;
        imageView.getLayoutParams().height = (int)getImageViewHeight(image.getHeight(),image.getWidth(),context.getResources().getDisplayMetrics().widthPixels, context.getResources().getDisplayMetrics().density);
 
        Log.e("SSS",String.valueOf(listView.getFirstVisiblePosition()+" "+i));
        imageView.setImageBitmap(null);
 
        imageLoader.displayImage(items.get(i).getLink(), imageView, options);
 
        return view;
чтобы добиться плавности прокрутки использую ViewHolder. После добавления новых элементов в список, вызываю notifydataset(). Все элементы в списке перерисовываются, соответственно картинки также перезагружаются (если картинка была в памяти, то она быстро перезагружается, но все же заметно, т.е. на долю секунды imageView становится пустым).
Если не использовать ViewHolder, то все нормально. Картинки которые пользователь сейчас видит не обновляются. Но при это производительность немного прокрутки списка падает.

Для загрузки картинок использую Universal Image Loader. Почти уверен что дело не в нем, т.к. пробовал обходиться и без него.
На всякий случай настроки UIL
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
options = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
                .cacheOnDisc(true)     
                .build();
        config = new ImageLoaderConfiguration.Builder(contex
                .tasksProcessingOrder(QueueProcessingType.FIFO) 
                //.denyCacheImageMultipleSizesInMemory()
                .discCacheSize(3 * 1024 * 1024)
                .threadPriority(Thread.NORM_PRIORITY-1)
                .threadPoolSize(3) // default
                .memoryCacheSize(3 * 1024 * 1024)
                .writeDebugLogs()
                .build();
Не знаю куда копать уже даже....
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2013, 04:11     После вызова notifydataset() items в listview "моргают"
Посмотрите здесь:
Android Как определить "переадресованность" входящего вызова
Ссылки (<a href="LINK">XXX</a>) внутри ListView Android
Android При прокрутке listview изображения подгружаются, но происходит "скачок" списка
Android Баг с items при прокручивании ListView
Отключить перескакивание между edittext после нажатия "готово" Android
Как программно убрать клавиатуру после нажатия кнопки "Далее"? Android
"Cannot resolve symbol R" после очистки проекта Android
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:03     После вызова notifydataset() items в listview "моргают" #16
Цитата Сообщение от V0v1k Посмотреть сообщение
зачем вообще высоту устанавливать в рантайме?
что бы "сжать" ImageView до высоты картинки. поскольку ImageView квадратная.
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 01:08     После вызова notifydataset() items в listview "моргают" #17
Цитата Сообщение от ta4 Посмотреть сообщение
А если использовать фиксированную высоту, тогда у картинок различная ширина, что смотрится очень некрасиво
android:scaleType="centerCrop" разве не то же самое дает что вы пытаетесь сделать?
можно просто фон назначить для картинок, будет лучше смотреться.

Добавлено через 1 минуту
Цитата Сообщение от Netscape Посмотреть сообщение
что бы "сжать" ImageView до высоты картинки.
XML
1
android:scaleType="centerInside"
Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:09     После вызова notifydataset() items в listview "моргают" #18
Похоже, это баг:
https://github.com/nostra13/Android-...der/issues/395

Попробуйте более старую версию, что ли. А то в последней много изменений, автор мог и накосячить где-то.
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 01:18  [ТС]     После вызова notifydataset() items в listview "моргают" #19
Цитата Сообщение от Netscape Посмотреть сообщение
Похоже, это баг:
https://github.com/nostra13/Android-...der/issues/395

Попробуйте более старую версию, что ли. А то в последней много изменений, автор мог и накосячить где-то.
Пробовал решение описанное по ссылке, тоже не работало. попробую заменить UIL другой подобной библиотекой для теста (или старую версию uil, как вы советуете).
Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:19     После вызова notifydataset() items в listview "моргают" #20
Цитата Сообщение от V0v1k Посмотреть сообщение
android:scaleType="centerInside"
Это не одно и тоже.
Миниатюры
После вызова notifydataset() items в listview "моргают"  
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 01:25     После вызова notifydataset() items в listview "моргают" #21
Цитата Сообщение от Netscape Посмотреть сообщение
Это не одно и тоже.
ну и в чем разница для пользователя между первым и по последним вариантов если ImageView не имеет фона?

Добавлено через 30 секунд
или вам ни один из этих вариантов не подходит? тогда нарисуйте как должно быть.
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 01:27  [ТС]     После вызова notifydataset() items в listview "моргают" #22
Цитата Сообщение от V0v1k Посмотреть сообщение
ну и в чем разница для пользователя между первым и по последним вариантов если ImageView не имеет фона?

Добавлено через 30 секунд
или вам ни один из этих вариантов не подходит? тогда нарисуйте как должно быть.
в первом варианте будут отступы большие между элементами в списке, в третьем отступов не будет
изображения идут одно за другим, отступы должны быть одинаковыми
Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:29     После вызова notifydataset() items в listview "моргают" #23
Цитата Сообщение от V0v1k Посмотреть сообщение
ну и в чем разница для пользователя между первым и по последним вариантов если ImageView не имеет фона?
Высота item'a списка бессмысленно большая.
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 01:29     После вызова notifydataset() items в listview "моргают" #24
то есть вы хотите чтобы айтемы списка были разной высоты?
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 01:31  [ТС]     После вызова notifydataset() items в listview "моргают" #25
Цитата Сообщение от V0v1k Посмотреть сообщение
то есть вы хотите чтобы айтемы списка были разной высоты?
да, высота item должна зависеть от картинки, которая внутри item'a
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 01:38     После вызова notifydataset() items в listview "моргают" #26
а, ну теперь стало понятно как оно должно выглядеть

Добавлено через 4 минуты
Цитата Сообщение от ta4 Посмотреть сообщение
если не использовать imageView.setImageBitmap(null); то высота иногда рассчитывается не правильно если быстро скроллить список.
просто в setImageBitmap вызывается requestLayout() и invalidate(), попробуйте добавить к тем изменениям что я писал раньше еще imageView.requestLayout()
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 01:51  [ТС]     После вызова notifydataset() items в listview "моргают" #27
Цитата Сообщение от V0v1k Посмотреть сообщение
а, ну теперь стало понятно как оно должно выглядеть

Добавлено через 4 минуты

просто в setImageBitmap вызывается requestLayout() и invalidate(), попробуйте добавить к тем изменениям что я писал раньше еще imageView.requestLayout()
если заменить в getView
Java
1
 imageView.setImageBitmap (null)
на
Java
1
2
3
 
imageView.requestLayout();
imageView.invalidate();
и добавить опцию .resetViewBeforeLoading(true)
то размер считается правильно, но "мерцание" изображений в imageView осталось при вызове notifyDataSetChanged() (похоже это действительно баг).
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 01:57     После вызова notifydataset() items в listview "моргают" #28
то если не использовать setTag то не мерцает? тогда можно попробовать вместо setTag например Map где ключом будет айтем, а значением holder.
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 02:07  [ТС]     После вызова notifydataset() items в listview "моргают" #29
Цитата Сообщение от V0v1k Посмотреть сообщение
то если не использовать setTag то не мерцает? тогда можно попробовать вместо setTag например Map где ключом будет айтем, а значением holder.
вряд ли в setTag дело. дело в том, что если не использовать viewHolder (т.е. не использовать "старые" элементы списка для показа новых), но появляются небольшие лаги при прокрутке списка.
вот такой getView будет работать без мерцания
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public View getView(int i, View view, ViewGroup viewGroup)
{
    ViewHolder vh;
    ImageView imageView;
    Image image = (Image)getItem(i);
    //if (view==null)
    //{
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.item, null);
        vh = new ViewHolder();
        vh.imageView = (ImageView) view.findViewById(R.id.imageView);
        view.setTag(vh);
    //}
    //else
    //{
        vh = (ViewHolder)view.getTag();
    //}
    imageView = vh.imageView;
    imageView.getLayoutParams().height = (int)getImageViewHeight(image.getHeight(),image.getWidth(),context.getResources().getDisplayMetrics().widthPixels, context.getResources().getDisplayMetrics().density);
    imageView.setImageBitmap(null);
    imageLoader.displayImage(items.get(i).getLink(), imageView, options);
    return view;
}
каждый раз "раздувается" R.layout.item, и ищется imageView (view.findViewById(R.id.imageView), что приводит к небольшим лагам
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.10.2013, 02:22     После вызова notifydataset() items в listview "моргают"
Еще ссылки по теме:
Android Метод вызова Activiti через ListView
Android Приложение падает после вызова finish
Пустой список после вызова adapter.notifyDataSetChanged Android
Как изменится стек после вызова активити другого приложения Android
Метод фрагмента onResume() перестает вызываться после вызова метода recreate() для Activity Android

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 02:22     После вызова notifydataset() items в listview "моргают" #30
поисследуйте чем таким отличается новый айтем от старого что это вызывает мерцание, подебагайте что в "Universal Image Loader" идет по другому. в чем-то же кроется причина.
Yandex
Объявления
01.10.2013, 02:22     После вызова notifydataset() items в listview "моргают"
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru