Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/10: Рейтинг темы: голосов - 10, средняя оценка - 5.00
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
1

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

30.09.2013, 04:11. Просмотров 1865. Ответов 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();
Не знаю куда копать уже даже....
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2013, 04:11
Ответы с готовыми решениями:

Как определить "переадресованность" входящего вызова
Доброго времени суток! Подскажите из какого свойства и каким образом можно...

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

Ссылки (<a href="LINK">XXX</a>) внутри ListView
Есть контент который я выкачиваю из интернета, и отображаю в листе. Контент...

При прокрутке listview изображения подгружаются, но происходит "скачок" списка
Здравствуйте. Использую listview и item с текстом и изображениями. При...

Работа с БД, связывание таблиц "фильмы", "жанры", "режиссеры"
Ребят, всем привет! накидайте какие-нить идеи по реализации ситуация такая...

30
V0v1k
1160 / 984 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 05:25 2
попробуйте использовать
Java
1
options.resetViewBeforeLoading();
вместо
Java
1
imageView.setImageBitmap(null);
1
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 17:51  [ТС] 3
попробовал, эффект тот же, но теперь и другая проблема. imageView у меня у каждого элемента списка имеет разную высоту, которая рассчитывается и устанавливается в getView. если не использовать
Java
1
imageView.setImageBitmap(null);
то высота иногда рассчитывается не правильно если быстро скроллить список.
0
V0v1k
1160 / 984 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 18:11 4
а почему она разная?
1
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 23:20  [ТС] 5
Цитата Сообщение от V0v1k Посмотреть сообщение
а почему она разная?
картинки имеют различное разрешение, я подгоняю все картинки по ширине listview. соответственно, если ширина картинки больше/меньше ширины listview,тогда я делю ширину listview на ширину картинки, получаю коэффициент, потом высоту картинки умножаю на этот коэффициент.
вот функция которая это делает

Java
1
2
3
4
5
6
7
public float getImageViewHeight(int imageHeight, int imageWidth, float needWidth, float density)
    {
        int sideMarginImageView = 24;
        int ivHeight = (int) (imageHeight*((needWidth)/imageWidth));
        ivHeight/=density;
        return ivHeight;
    }
0
V0v1k
1160 / 984 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 23:34 6
вы imageView подгоняете а не картинку, я так понял вы с scaleType'ом запутались....
впервые вижу такое.
1
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 23:47  [ТС] 7
Цитата Сообщение от V0v1k Посмотреть сообщение
вы imageView подгоняете а не картинку, я так понял вы с scaleType'ом запутались....
спасибо, кажется в этом проблема. сейчас попробую

Добавлено через 10 минут
спасибо за помощь, V0v1k!
действительно, если задать фиксированный размер imageview, то все работает прекрасно, но мне нужно каким-то образом подгонять размер imageview под картинку. размеры картинок мне известны еще до загрузки. т.е. пользователь должен видеть пустой imageView уже нужного размера, пока картинка грузится.
0
V0v1k
1160 / 984 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 23:53 8
Цитата Сообщение от ta4 Посмотреть сообщение
но мне нужно каким-то образом подгонять размер imageview под картинку.
зачем?

Добавлено через 1 минуту
обычно картинка подгоняется под ImageView
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
30.09.2013, 23:55 9
Цитата Сообщение от ta4 Посмотреть сообщение
но мне нужно каким-то образом подгонять размер imageview под картинку
Пишите свой imageview, с барышнями и преферансом.
Кликните здесь для просмотра всего текста
Вот так, например, подгоняется высота imageview, ширину уже сами прикрутите.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
 
public class ResizableImageView extends ImageView {
    
    public ResizableImageView(Context context) {
        super(context);
    }
 
    public ResizableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Drawable d = getDrawable();
        if (d != null) {
            // ceil not round - avoid thin vertical gaps along the left/right  edges
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = (int) Math.ceil((float) width
                    * (float) d.getIntrinsicHeight()
                    / (float) d.getIntrinsicWidth());
            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    
}
1
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 23:59  [ТС] 10
Цитата Сообщение от Netscape Посмотреть сообщение
Пишите свой imageview, с барышнями и преферансом.
спасибо, то что нужно
0
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 00:42  [ТС] 11
Цитата Сообщение от ta4 Посмотреть сообщение
спасибо, то что нужно
опять же появилась проблема описанная в первом сообщении. При вызове notifyDataSet() у адаптера списка, начинают перезагружаться все imageView. Если не рассчитывать высоту для imageView (установить постоянную, что мне не подходит) или не использовать viewHolder (без него лаги), то все работает нормально.

метод из моего imageView
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Drawable d = getDrawable();
        if (d != null) {
            // ceil not round - avoid thin vertical gaps along the left/right  edges
            float width = MeasureSpec.getSize(widthMeasureSpec);
            float height = (width/wid*hei);//wid и hei ширина картинки, которая будет загружена из сети
            //Log.e("mes", ""+d.getIntrinsicHeight()+"x"+d.getIntrinsicWidth()+"");
            setMeasuredDimension((int)width, (int)height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 00:49 12
Цитата Сообщение от ta4 Посмотреть сообщение
При вызове notifyDataSet() у адаптера списка
А зачем его, собственно, вызывать ?
После удачной загрузки изображения UIL вызывает у imageView метод requestLayout(), после чего изображение обновляется.
Цитата Сообщение от ta4 Посмотреть сообщение
imageView.setImageBitmap(null);
это вообще зачем ?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder vh;
        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;
        imageLoader.displayImage(items.get(i).getLink(), vh.imageView, options);
 
        return view;
}
0
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 00:55  [ТС] 13
Цитата Сообщение от Netscape Посмотреть сообщение
А зачем его, собственно, вызывать ?
После удачной загрузки изображения UIL вызывает у imageView метод requestLayout(), после чего изображение обновляется.

это вообще зачем ?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder vh;
        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;
        imageLoader.displayImage(items.get(i).getLink(), vh.imageView, options);
 
        return view;
}
notifyDataSet вызываю, т.к. добавляю новые элементы в конец listView

Java
1
imageView.setImageBitmap(null);
в этой строке может быть косяк. Использую, т.к. при прокрутке списка с использование viewHolder переиспользуются элементы списка, которые уже были показаны и если в "старом "элементе уже показывалась какая-то картинка, то она будет показываться и в "новом", поэтому этой строкой очищаю imageView
0
V0v1k
1160 / 984 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 00:57 14
зачем вообще высоту устанавливать в рантайме?
0
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 01:02  [ТС] 15
Цитата Сообщение от V0v1k Посмотреть сообщение
зачем вообще высоту устанавливать в рантайме?
чтобы не было "скачков", когда imageview меньше картинки по высоте. т.е. картинка загрузилась и imageview неожиданно увеличился по высоте. когда список состоит из одних картинок такое поведение напрягает. А если использовать фиксированную высоту, тогда у картинок различная ширина, что смотрится очень некрасиво
к примеру, в приложении kate mobile (в "новости") реализовано так как я пытаюсь сделать, да во многих приложениях так сделано (где изображения в списке различной высоты), но как пока не могу понять..
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:03 16
Цитата Сообщение от V0v1k Посмотреть сообщение
зачем вообще высоту устанавливать в рантайме?
что бы "сжать" ImageView до высоты картинки. поскольку ImageView квадратная.
0
V0v1k
1160 / 984 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 01:08 17
Цитата Сообщение от ta4 Посмотреть сообщение
А если использовать фиксированную высоту, тогда у картинок различная ширина, что смотрится очень некрасиво
android:scaleType="centerCrop" разве не то же самое дает что вы пытаетесь сделать?
можно просто фон назначить для картинок, будет лучше смотреться.

Добавлено через 1 минуту
Цитата Сообщение от Netscape Посмотреть сообщение
что бы "сжать" ImageView до высоты картинки.
XML
1
android:scaleType="centerInside"
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:09 18
Похоже, это баг:
https://github.com/nostra13/Android-Universal-Image-Loader/issues/395

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

Попробуйте более старую версию, что ли. А то в последней много изменений, автор мог и накосячить где-то.
Пробовал решение описанное по ссылке, тоже не работало. попробую заменить UIL другой подобной библиотекой для теста (или старую версию uil, как вы советуете).
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
01.10.2013, 01:19 20
Цитата Сообщение от V0v1k Посмотреть сообщение
android:scaleType="centerInside"
Это не одно и тоже.
0
Миниатюры
После вызова notifydataset() items в listview "моргают"  
01.10.2013, 01:19
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.10.2013, 01:19

Ошибка "Unknown method "e" of "org.apache.commons.logging.Log"
Unknown method 'e' of 'org.apache.commons.logging.Log' package...

Баг с items при прокручивании ListView
Суть такая, что выводится список ListView. Там items могут быть двух разных...

Отключить перескакивание между edittext после нажатия "готово"
После нажатия на кнопку готово происходит заполнение второго edittext, третьего...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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