Estamos sofrendo de um problema muito estranho com o ViewPager aqui. Incorporamos listas em cada página do ViewPager e disparamos o notifigDataSetChanged no adaptador de lista e no adaptador de pager de visualização ao atualizar os dados da lista.
O que observamos é que às vezes a página não atualiza sua árvore de visualização, ou seja, permanece em branco, ou às vezes até desaparece ao ser paginada. Ao retroceder e avançar algumas vezes, o conteúdo reaparecerá repentinamente. Parece que o Android está perdendo uma atualização de visualização aqui. Também percebi que, ao depurar com o visualizador de hierarquia, selecionar uma visualização sempre fará com que ela reapareça, aparentemente porque o visualizador de hierarquia força a visualização selecionada a se redesenhar.
Eu não poderia fazer este trabalho programaticamente; invalidar a exibição de lista, ou até mesmo o pager de exibição inteiro, não teve nenhum efeito.
Isso é com a biblioteca compatibilidade-v4_r7. Também tentei usar a revisão mais recente, uma vez que afirma corrigir muitos problemas relacionados à visualização do pager, mas tornou as coisas ainda piores (por exemplo, os gestos foram interrompidos para que às vezes não me deixasse folhear todas as páginas).
Alguém mais está enfrentando esses problemas também ou você tem uma ideia do que pode estar causando isso?
fonte
Se o
ViewPager
for definido dentro de um Fragment com umFragmentPagerAdapter
, use emgetChildFragmentManager()
vez degetSupportFragmentManager()
como o parâmetro para inicializar seuFragmentPagerAdapter
.mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
Ao invés de
mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
fonte
getItem()
umFragmentPagerAdapter
que estava aninhado em um fragmento recriado.Eu tive exatamente o mesmo problema, mas na verdade destruí a visualização em destroyItem (pensei). O problema, entretanto, é que eu o destruí usando em
viewPager.removeViewAt(index);
vez deviewPager.removeView((View) object);
Errado:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeViewAt(position); }
Direito:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeView((View) object); }
fonte
ViewPager tenta fazer coisas inteligentes em torno da reutilização de itens, mas requer que você retorne novas posições de item quando as coisas mudaram. Tente adicionar ao seu PagerAdapter:
public int getItemPosition (Object object) { return POSITION_NONE; }
Basicamente, diz ao ViewPager que tudo mudou (e força a instanciar tudo novamente). Essa é a única coisa que consigo pensar de cabeça.
fonte
return POSITION_NONE;
,forces it to re-instantiate everything
mas no meu caso não quero instanciar tudo novamente , então seria possível removerview
sem limpar o material existente? Informe-meTentei muitas soluções, mas
viewPager.post()
funcionou inesperadamentemAdapter = new NewsVPAdapter(getContext(), articles); viewPager.post(new Runnable() { @Override public void run() { viewPager.setAdapter(mAdapter); } });
fonte
A Android Support Library tem uma atividade de demonstração que inclui um ViewPager com um ListView em cada página. Você provavelmente deveria dar uma olhada e ver o que ele faz.
No Eclipse (com Android Dev Tools r20):
New > Android Sample Project
Support4Demos
Android Tools > Add Support Library
Fragment
e depoisPager
O código para isso está em
src/com.example.android.supportv4.app/FragmentPagerSupport.java
. Boa sorte!fonte
Corri para isso e tive problemas muito semelhantes. Eu até perguntei sobre estouro de pilha.
Para mim, no pai do pai da minha visão, alguém
LinearLayout
criou uma subclasse e substituiurequestLayout()
sem chamarsuper.requestLayout()
. Isso evitouonMeasure
eonLayout
foi chamado no meu ViewPager (embora o hierarchyviewer os chame manualmente). Sem serem medidos, eles aparecerão em branco no ViewPager.Portanto, verifique suas visualizações. Certifique-se de que eles tenham subclasses de View e não sobrescrevam requestLayout ou algo semelhante.
fonte
Tive o mesmo problema, que é algo a ver com
ListView
(porque minha visualização vazia aparece bem se a lista estiver vazia). Acabei derequestLayout()
ligar para a problemáticaListView
. Agora está tudo bem!fonte
Eu tive esse mesmo problema ao usar um ViewPager e FragmentStatePagerAdapter. Tentei usar um manipulador com um atraso de 3 segundos para chamar invalidate () e requestLayout (), mas não funcionou. O que funcionou foi redefinir a cor de fundo do viewPager da seguinte maneira:
MyFragment.java
private Handler mHandler; private Runnable mBugUpdater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = new ViewPager(getActivity()); //...Create your adapter and set it here... mHandler = new Handler(); mBugUpdater = new Runnable(){ @Override public void run() { mVp.setBackgroundColor(mItem.getBackgroundColor()); mHandler = null; mBugUpdater = null; } }; mHandler.postDelayed(mBugUpdater,50); return rootView; } @Override public void onPause() { if(mHandler != null){ //Remove the callback if it hasn't triggered yet mHandler.removeCallbacks(mBugUpdater); mHandler = null; mBugUpdater = null; } super.onPause(); }
fonte
Tive um problema com os mesmos sintomas, mas uma causa diferente que acabou sendo um erro bobo da minha parte. Pensei em adicioná-lo aqui para o caso de ajudar alguém.
Eu tinha um ViewPager usando FragmentStatePagerAdapter que costumava ter dois fragmentos, mas depois adicionei um terceiro. No entanto, esqueci que o limite padrão de página fora da tela é 1 - então, quando eu mudasse para o novo terceiro fragmento, o primeiro seria destruído e recriado após voltar. O problema era que minha atividade era responsável por notificar esses fragmentos para inicializar seu estado de IU. Isso funcionava quando os ciclos de vida de atividade e fragmento eram os mesmos, mas para consertar eu tive que mudar os fragmentos para inicializar sua própria IU durante seu ciclo de vida de inicialização. No final, também acabei alterando setOffscreenPageLimit para 2, de modo que todos os três fragmentos fossem mantidos vivos o tempo todo (seguro neste caso, já que eles não exigiam muita memória).
fonte
Eu tive um problema semelhante. Coloco visualizações em cache porque preciso de apenas 3 visualizações em
ViewPager
. Quando eu deslizo para frente está tudo bem, mas quando eu começo a deslizar para trás ocorre um erro, ele diz que "minha visão já tem um pai". A solução é excluir itens desnecessários manualmente.@Override public Object instantiateItem(ViewGroup container, int position) { int localPos = position % SIZE; TouchImageView view; if (touchImageViews[localPos] != null) { view = touchImageViews[localPos]; } else { view = new TouchImageView(container.getContext()); view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); touchImageViews[localPos] = view; } view.setImageDrawable(mDataModel.getPhoto(position)); Log.i(IRViewPagerAdpt.class.toString(), "Add view " + view.toString() + " at pos: " + position + " " + localPos); if (view.getParent() == null) { ((ViewPager) container).addView(view); } return view; } @Override public void destroyItem(ViewGroup container, int position, Object view) { // ((ViewPager) container).removeView((View) view); Log.i(IRViewPagerAdpt.class.toString(), "remove view " + view.toString() + " at pos: " + position); } .................. private static final int SIZE = 3; private TouchImageView[] touchImageViews = new TouchImageView[SIZE];
fonte
Para mim, o problema era voltar à atividade depois que o processo do aplicativo foi encerrado. Estou usando um adaptador de pager de visualização customizado modificado das fontes do Android. O pager de visualização está incorporado diretamente na atividade.
Chamando
viewPager.setCurrentItem(position, true);
(com animação) depois de definir os dados e notificarDataSetChanged () parece funcionar, mas se o parâmetro for definido como falso, ele não funciona e o fragmento está em branco. Este é um caso extremo que pode ser útil para alguém.
fonte