Страница 1 из 2

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

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

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

Добавлено: 23 авг 2012, 06:56
KamiSempai
Прорисовка View происходит в onDraw? Если нет, каким способом прорисовываете View?

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

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

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

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

Добавлено: 23 авг 2012, 08:13
KamiSempai
Тут скорее всего проблема не в ViewPager а в View.
Что это за компонент?

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

Добавлено: 23 авг 2012, 08:24
math64
нужно искать как включить двойную буферизацию - тогода мигание пропадёт.

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

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

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

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

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

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

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

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

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

Добавлено: 23 авг 2012, 09:39
KamiSempai
Может стоит копать в ту сторону, что после перелистывания, содержимое всех View меняется и активной становится средняя страница?
Подобная вещь в ближайшем будущем мне тоже понадобится, могу помочь если скинете исходники в личку.

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

Добавлено: 23 авг 2012, 10:16
neoksi
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;
            }
            
		});
Первые варианты вылетали, но вот этот уже стабильно работает и не тормозит.

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

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

PS: Сегодня вечером попробую сделать что-нибудь вменяемое.

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

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

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

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

Добавлено: 13 янв 2013, 23:55
RUSSTARUS
Здравствуйте! Помогите пожалуйста разобраться с обновлением 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 еще пока не силён, помогите кто может...
(писал в основном всё по примерам...)

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

Добавлено: 14 янв 2013, 01:19
Finch
делаешь все что нужно с вьюхой потом вызываешь notifyDataSetChanged(), а вообще лучше юзать фрагменты =)

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

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

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

Добавлено: 15 янв 2013, 01:10
KamiSempai
Скажите, хотя бы, какую ошибку выдает. А лучше лог выложите. Только не скриншот а текстовый вариант.

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

Добавлено: 15 янв 2013, 01:15
rezak90
я бы рекомендовал юзать фрагмент и во фрагменте реализовывать нужный функционал, тогда от адаптера с viewpager'a можем получить ссылку на фрагмент и сделать ему onResume или же onCreateView что его и пересоздаст

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

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

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

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

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

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

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

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