ViewPager и обновление View

Интерфейс, диалоги, темы, стили, меню
Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 04:48

Привет всем!
ViewPager в памяти хранит 3 прорисованных View, для быстрого их отображения. Если я меняю наполнение одного из View, что находится в памяти и еще не отображается, то при получении фокуса он у меня мигает (один раз, видно что пошла прорисовка). Вопрос в том, какие мне необходимо задать команды этому View, чтоб он прорисовался в памяти?

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: ViewPager и обновление View

Сообщение KamiSempai » 23 авг 2012, 06:56

Прорисовка View происходит в onDraw? Если нет, каким способом прорисовываете View?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 07:48

KamiSempai писал(а):Прорисовка View происходит в onDraw? Если нет, каким способом прорисовываете View?
Честно 5 часов искал в исходниках ViewPager и в его родителях, как же они делают прорисовку, так точного ответа и не нашел, в основном там идут вызовы invalidate() и requestLayout(), но метода прямого вызова перерисовки так и не нашел...

Пробовал 2 варианта адаптеров, оба работают, но присутствует это раздражающее мигание, при перелистывании.
В результате зародилась идея, вот таким способом (View) cPager.getChildAt(0) получить ссылку на View из ViewPager, обновить его, и сразу же дать команду на перерисовку, через вызов методов invalidate() и requestLayout() в View, но это эффекта не дало, все равно мигает =(.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: ViewPager и обновление View

Сообщение KamiSempai » 23 авг 2012, 08:13

Тут скорее всего проблема не в ViewPager а в View.
Что это за компонент?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: ViewPager и обновление View

Сообщение math64 » 23 авг 2012, 08:24

нужно искать как включить двойную буферизацию - тогода мигание пропадёт.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 08:25

KamiSempai писал(а):Тут скорее всего проблема не в ViewPager а в View.
Что это за компонент?
View - это объект, в который мы делаем inflate из xml шаблонов, а потом заполняем его данными и отдаем на отрисовку. Все UI Androida это View объекты.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 08:26

math64 писал(а):нужно искать как включить двойную буферизацию - тогода мигание пропадёт.
А где об этом почитать? А то впервые слышу, сам копал в сторону кеширования...

math64
Сообщения: 235
Зарегистрирован: 16 июл 2012, 07:47

Re: ViewPager и обновление View

Сообщение math64 » 23 авг 2012, 08:34

Виджет рисуется не на экран, а в битмап. Потом этот битмап выводится на экран. Тогда мигания не будет. Как это делается в Андроиде не знаю, а ссылки, как это делается в других гуи вам не помогут.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 08:41

math64 писал(а):Виджет рисуется не на экран, а в битмап. Потом этот битмап выводится на экран. Тогда мигания не будет. Как это делается в Андроиде не знаю, а ссылки, как это делается в других гуи вам не помогут.
Душой я это понял, но разум пока не нашел, как это делается в этом Гуи, какой метод нужно вызвать. ;)

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: ViewPager и обновление View

Сообщение KamiSempai » 23 авг 2012, 09:39

Может стоит копать в ту сторону, что после перелистывания, содержимое всех View меняется и активной становится средняя страница?
Подобная вещь в ближайшем будущем мне тоже понадобится, могу помочь если скинете исходники в личку.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 10:16

KamiSempai писал(а):Может стоит копать в ту сторону, что после перелистывания, содержимое всех View меняется и активной становится средняя страница?
Подобная вещь в ближайшем будущем мне тоже понадобится, могу помочь если скинете исходники в личку.
Я как раз это и реализую. По логике все просто должно быть, от средней страницы мы листаем вбок, далее в невидимой зоне перегружаем среднюю страницу, без эффектов переводим отображение на среднюю страницу и перезагружаем боковые страницы. Но у меня никак не получается заставить ViewPager, поочередно перезагрузить страницы. Он их перезагружает, только когда я возвращаю его на среднюю страницу.

Мне сейчас сложно выцепить полноценный кусок из программы для отдельных тестов =(

Но для общего понимания, вот мои потуги:
< ----- Удалил. ------>


Решение проблемы нашлось, через потоки. Алгоритм получился следующим:

Код: Выделить всё

cTitleIndicator.setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {
            	if (state == ViewPager.SCROLL_STATE_IDLE) {
            		
            		if (focusedPage == 0) {            			
            			new Handler().post(new Runnable() {
            				@Override
            				public void run() {
		            			for(int i=0;i<3;i++){
		            					cArray[i].prevMonth();
		                				taCalendarViewMaker.makeGrid(ctx, views[i], cArray[i]);		                				
		                				if(i==currentSelView){
		                					cTitleIndicator.setCurrentItem(currentSelView, false); 
		                				} 
		                				
		            			}
            				
            				}
            			});             			
            		} else if (focusedPage == 2) {
            			new Handler().post(new Runnable() {
            				@Override
            				public void run() {
		            			for(int i=0;i<3;i++){	
		            					cArray[i].nextMonth();   
		                				taCalendarViewMaker.makeGrid(ctx, views[i], cArray[i]);		                				
		                				if(i==currentSelView){
		                					cTitleIndicator.setCurrentItem(currentSelView, false); 
		                				}
		            			}
            				}
            			});
            		} 
            	}
            }

            @Override
            public void onPageSelected(int position) {
            	focusedPage = position;
            }
            
		});
Первые варианты вылетали, но вот этот уже стабильно работает и не тормозит.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: ViewPager и обновление View

Сообщение KamiSempai » 23 авг 2012, 11:48

Мне не нравится cViewPages.clear() и setNewData, в оригинальном коде этого не было.
Получается, при каждом перелистывании все страницы уничтожаются и создаются новые.

PS: Сегодня вечером попробую сделать что-нибудь вменяемое.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 23 авг 2012, 12:06

KamiSempai писал(а):Мне не нравится cViewPages.clear() и setNewData, в оригинальном коде этого не было.
Получается, при каждом перелистывании все страницы уничтожаются и создаются новые.

PS: Сегодня вечером попробую сделать что-нибудь вменяемое.
cViewPages.clear() и setNewData - от них избавился в конечном варианте =)
Они появились как одна из многих попыток заставить работать)

RUSSTARUS
Сообщения: 3
Зарегистрирован: 13 янв 2013, 21:57
Откуда: Волгоград

Re: ViewPager и обновление View

Сообщение RUSSTARUS » 13 янв 2013, 23:55

Здравствуйте! Помогите пожалуйста разобраться с обновлением view в viewpager - как это сделать?
Изучаю ANDROID (2 месячный стаж) не силён пока, но кое-что разобрал.

Вопрос как обновить одну из страниц viewpager?
Есть класс Draw2D от view где в методе onDraw рисуется что - то в канве.
создан объект d класса (Draw2D d = new Draw2D(this)) в активите и помещен в List<View> pages вот так примерно (pages.add(d)) ,так-же

есть и другие страницы добавленно так-же pages.add(...), но они из layout xml

затем:
SamplePagerAdapter pagerAdapter = new SamplePagerAdapter(pages);

ViewPager vp = (ViewPager) findViewById(R.id.viewpager);
vp.setAdapter(pagerAdapter);

ViewPager отображается на главном layoutе.main (всё работает, страницы листаются их 4)

Мне нужно в таймере перерисовывать Draw2D (обновление канвы на одной странице)
Как мне это правильно сделать?

Пробовал вызывать из таймера это: Draw2D.invalidate() (и postInvalidate) всё компилирует, но при срабатывании таймера - приложение вылетает...
Вопрос, что мне надо сделать с viewpager и может с адаптером в таймере для обновления только одной этой страницы view из класса Draw2D .

С адаптерами и viewpager еще пока не силён, помогите кто может...
(писал в основном всё по примерам...)

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

Re: ViewPager и обновление View

Сообщение Finch » 14 янв 2013, 01:19

делаешь все что нужно с вьюхой потом вызываешь notifyDataSetChanged(), а вообще лучше юзать фрагменты =)
CEO of a company R.id.team

RUSSTARUS
Сообщения: 3
Зарегистрирован: 13 янв 2013, 21:57
Откуда: Волгоград

Re: ViewPager и обновление View

Сообщение RUSSTARUS » 14 янв 2013, 03:34

Ну вот я и хотел только сделать invalidate() (Перерисовать всё что в методе onDraw), но приложение вылетает. Как перерисовывать правильно ???

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: ViewPager и обновление View

Сообщение KamiSempai » 15 янв 2013, 01:10

Скажите, хотя бы, какую ошибку выдает. А лучше лог выложите. Только не скриншот а текстовый вариант.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: ViewPager и обновление View

Сообщение rezak90 » 15 янв 2013, 01:15

я бы рекомендовал юзать фрагмент и во фрагменте реализовывать нужный функционал, тогда от адаптера с viewpager'a можем получить ссылку на фрагмент и сделать ему onResume или же onCreateView что его и пересоздаст
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ViewPager и обновление View

Сообщение neoksi » 15 янв 2013, 09:24

RUSSTARUS
Что-то у меня подозрения, что ты из другого потока пытаешься ненадлежащим образом обновить поток UI.

RUSSTARUS
Сообщения: 3
Зарегистрирован: 13 янв 2013, 21:57
Откуда: Волгоград

Re: ViewPager и обновление View

Сообщение RUSSTARUS » 15 янв 2013, 20:55

Пробовал просто pageAdapter.notifyDataSetChanged() через runOnUiThread из таймера запускать - всё равно вылетает.
Вообще notifyDataSetChanged() применяют после изменения данных в адаптерах: add, clear, так???
Вопрос если мы хотим перерисовать view который в данный момент например не виден - это правильно???

Запуск vp.invalidate() через runOnUiThread из таймера тоже успехом не увенчался... (vp это viewPager)
Сам таймер без этих команд отрабатывает нормально.

А таймер всегда выполняет задачу timerTask в своём потоке который создаёт сам???

С фрагментами не работал (нужно всё переделывать наверное, да и сложнее разобраться), а компилирую сразу на реальном устройстве с помощью приложения Anjedi (отлично компилятор работает!)

Вообще какой правильный подход в моём случае? Помогите разобраться.

Ответить