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

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

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

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

30.09.2013, 04:11. Просмотров 1686. Ответов 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):

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

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

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

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

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

Ошибка "Unknown method "e" of "org.apache.commons.logging.Log" - Программирование Android
Unknown method 'e' of 'org.apache.commons.logging.Log' package com.mycompany.myapp; import android.widget.*; import...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 05:25 #2
попробуйте использовать
Java
1
options.resetViewBeforeLoading();
вместо
Java
1
imageView.setImageBitmap(null);
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 17:51  [ТС] #3
попробовал, эффект тот же, но теперь и другая проблема. imageView у меня у каждого элемента списка имеет разную высоту, которая рассчитывается и устанавливается в getView. если не использовать
Java
1
imageView.setImageBitmap(null);
то высота иногда рассчитывается не правильно если быстро скроллить список.
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 18:11 #4
а почему она разная?
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;
    }
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
30.09.2013, 23:34 #6
вы imageView подгоняете а не картинку, я так понял вы с scaleType'ом запутались....
впервые вижу такое.
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 23:47  [ТС] #7
Цитата Сообщение от V0v1k Посмотреть сообщение
вы imageView подгоняете а не картинку, я так понял вы с scaleType'ом запутались....
спасибо, кажется в этом проблема. сейчас попробую

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

Добавлено через 1 минуту
обычно картинка подгоняется под ImageView
Netscape
371 / 358 / 48
Регистрация: 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);
        }
    }
    
}
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
30.09.2013, 23:59  [ТС] #10
Цитата Сообщение от Netscape Посмотреть сообщение
Пишите свой imageview, с барышнями и преферансом.
спасибо, то что нужно
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);
        }
    }
Netscape
371 / 358 / 48
Регистрация: 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;
}
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
V0v1k
1158 / 982 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
01.10.2013, 00:57 #14
зачем вообще высоту устанавливать в рантайме?
ta4
0 / 0 / 0
Регистрация: 09.05.2012
Сообщений: 19
01.10.2013, 01:02  [ТС] #15
Цитата Сообщение от V0v1k Посмотреть сообщение
зачем вообще высоту устанавливать в рантайме?
чтобы не было "скачков", когда imageview меньше картинки по высоте. т.е. картинка загрузилась и imageview неожиданно увеличился по высоте. когда список состоит из одних картинок такое поведение напрягает. А если использовать фиксированную высоту, тогда у картинок различная ширина, что смотрится очень некрасиво
к примеру, в приложении kate mobile (в "новости") реализовано так как я пытаюсь сделать, да во многих приложениях так сделано (где изображения в списке различной высоты), но как пока не могу понять..
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.10.2013, 01:02
Привет! Вот еще темы с ответами:

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

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

Как программно убрать клавиатуру после нажатия кнопки "Далее"? - Программирование Android
Здравствуйте, уважаемые форумчане. Я недавно начал изучать android и столкнулся со следующей проблемой: я сделал поле ввода, и после ввода...

"Cannot resolve symbol R" после очистки проекта - Программирование Android
Был нормальный проект, но вот я решил его почистить. Почистил. Теперь у меня не проект, а консерва с гайками. Пишет мол Cannot resolve...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.10.2013, 01:02
Ответ Создать тему
Опции темы

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