studio - viewpager with fragments example in android




FragmentPagerAdapter getItem não é chamado (5)

Descobri que configurar um ouvinte no layout de guia impedia que isso fosse chamado, provavelmente porque eles só têm espaço para um ouvinte em tabLayout.setOnTabSelectedListener em vez de uma matriz de ouvintes.

Eu não sou capaz de reutilizar fragmento em FragmentPagerAdapter .. Usando o método destroyItem (), ele está excluindo o fragmento, mas ainda não chamado getItem () novamente .. Há apenas 2-3 imagens, então eu estou usando FragmentPagerAdapter em vez de FragmentStatePagerAdapter ..

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

E em FragmentActivity,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 

Eu fiz o que @kanika e @ Jraco11 haviam postado, mas eu ainda tinha o problema.

Então, depois de muitas mudanças, encontrei uma que funcionou para mim e foi adicionada ao meu FragmentPagerAdapter no próximo código:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

De acordo com o que eu li, getItemPosition é usado para notificar o ViewPager se deve ou não atualizar um item, e evitar atualizações se os itens nas posições visíveis não tiverem mudado.


O método getItem() é usado apenas para criar novos itens. Depois de criados, esse método não será chamado. Se você precisar obter o item que está em uso pelo adaptador, use este método:

pagerAdapter.instantiateItem(viewPager, TAB_POS)

O uso de um FragmentStatePagerAdapter não corrigiu totalmente o meu problema, que era um problema semelhante, no qual o onCreateView não estava sendo chamado para fragmentos filhos no paginador de exibição. Na verdade, estou aninhando meu FragmentPagerAdapter dentro de outro Fragment portanto, o FragmentManager foi compartilhado em todos eles e, assim, retendo instâncias dos fragmentos antigos. A correção foi, em vez disso, alimentar uma instância do getChildFragmentManager para o construtor do FragmentPagerAdapter no meu fragmento de host. Algo como...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

O método getChildFragmentManager() é acessível por meio de um fragmento e isso funcionou para mim, porque ele retorna um FragmentManager particular para esse fragmento especificamente para situações em que os fragmentos de aninhamento são necessários. Espero que isso ajude alguém que pode estar tendo o mesmo problema que eu estava !!

  • No entanto, tenha em mente que para usar o getChildFragmentManager() sua versão mínima da API deve ter no mínimo 17 (4.2) , portanto, isso pode colocar uma chave em suas engrenagens. Claro, se você estiver usando fragmentos da biblioteca de suporte v4, você deve estar bem.

Substituir long getItemId (int position)

FragmentPagerAdapter armazena em cache os fragmentos que cria usando getItem . Eu estava enfrentando o mesmo problema, mesmo depois de chamar notifyDataSetChanged() getItem não estava sendo chamado.

Este é realmente um recurso e não um bug. Você precisa substituir getItemId para poder reutilizar seus fragmentos corretamente. Como você está removendo fragmentos, suas posições estão mudando. Conforme mencionado nos documentos:

long getItemId (int position)

Retorna um identificador exclusivo para o item na posição determinada.

A implementação padrão retorna a posição dada. Subclasses devem sobrescrever este método se as posições dos itens puderem mudar.

Apenas forneça um ID exclusivo para cada fragmento e pronto.

Usar um FragementStatePagerAdapter ou retornar POSITION_NONE em int getItemPosition (Object object) está incorreto. Você não receberá nenhum cache.





android-fragmentactivity