I cannot replace the fragments displayed in Viewpager

Asked

Viewed 341 times

2

I am retracing the navigation of an application so that it works as follows: the application consists of a single activity that initially displays a ViewPager with three views (Fragments), and in one of the views there is a button that replaces these Fragments with two new Fragments.

I found out in this OS response I can’t use FragmentPagerAdapter for this never destroys a fragment after displaying it for the first time; as I wish to exchange the fragments, I have to use FragmentStatePagerAdapter taking care to always return a new fragment instance in the method getItem(int position). But so that the ViewPager effectively update the views displayed after the Adapter associated with it (I don’t actually change the Adapter, I just change the data associated with it, which I use to instantiate the fragments), I must override the method getItemPosition(Object object) to return POSITION_NONE and call notifyDataSetChanged() in the Adapter. However, this is not causing the views to be updated (and this is precisely my problem).

Follows my code:

Configurations in the viewpager.java:

public static class ConfiguracoesDeItemDoViewPager {

    private String nomeDaAba;
    private Class<? extends FragmentoBase> classeDoFragmento;
    private Bundle argumentosDoFragmento;

    public ConfiguracoesDeItemDoViewPager(String nomeDaAba, Class<? extends FragmentoBase> classeDoFragmento, Bundle argumentosDoFragmento) {
        this.nomeDaAba = nomeDaAba;
        this.classeDoFragmento = classeDoFragmento;
        this.argumentosDoFragmento = argumentosDoFragmento;
    }

    public String getNomeDaAba() {
        return nomeDaAba;
    }

    public void setNomeDaAba(String nomeDaAba) {
        this.nomeDaAba = nomeDaAba;
    }

    public Class<? extends FragmentoBase> getClasseDoFragmento() {
        return classeDoFragmento;
    }

    public void setClasseDoFragmento(
            Class<? extends FragmentoBase> classeDoFragmento) {
        this.classeDoFragmento = classeDoFragmento;
    }

    public Bundle getArgumentosDoFragmento() {
        return argumentosDoFragmento;
    }

    public void setArgumentosDoFragmento(Bundle argumentosDoFragmento) {
        this.argumentosDoFragmento = argumentosDoFragmento;
    }
}

Java constants.:

public class Constantes {

    public static final ConfiguracoesDeItemDoViewPager [] CONFIGURACOES_DO_VIEWPAGER_1;
    public static final ConfiguracoesDeItemDoViewPager [] CONFIGURACOES_DO_VIEWPAGER_2;

    // Bloco de inicialização de valores estáticos 
    static {
        CONFIGURACOES_DO_VIEWPAGER_1 = new DadosDeItemDoViewPager[3];
        CONFIGURACOES_DO_VIEWPAGER_1[0] = new DadosDeItemDoViewPager("Aba 1", FragmentoA.class, null);
        CONFIGURACOES_DO_VIEWPAGER_1[1] = new DadosDeItemDoViewPager("Aba 2", FragmentoB.class, null);
        CONFIGURACOES_DO_VIEWPAGER_1[2] = new DadosDeItemDoViewPager("Aba 3", FragmentoC.class, null);

        CONFIGURACOES_DO_VIEWPAGER_2 = new DadosDeItemDoViewPager[2];
        CONFIGURACOES_DO_VIEWPAGER_2[0] = new DadosDeItemDoViewPager("Aba 1", FragmentoD.class, null);
        CONFIGURACOES_DO_VIEWPAGER_2[1] = new DadosDeItemDoViewPager("Aba 2", FragmentoE.class, null);
    }

...

}

Activity of the core.java:

public class AtividadePrincipal extends ActionBarActivity {

    private ViewPager mViewPager;
    private TabsPagerAdapter mTabsPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mTabsPagerAdapter = new TabsPagerAdapter(getSupportFragmentManager(), Constantes.CONFIGURACOES_DO_VIEWPAGER_1);
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mTabsPagerAdapter);
    }

    public void exibirViewPager2() {
        ((TabsPagerAdapter)mViewPager.getAdapter()).setConfiguracoesParaInicializarViewPager(Constantes.CONFIGURACOES_DO_VIEWPAGER_2);
    }

    public class TabsPagerAdapter extends FragmentStatePagerAdapter {

        private FragmentManager mFragmentManager; 
        private ConfiguracoesDeItemDoViewPager [] mConfiguracoesDeItensDoViewPager;

        public TabsPagerAdapter(FragmentManager fm, ConfiguracoesDeItensDoViewPager [] configuracoesDeItensDoViewPager) {
            super(fm);
            this.mFragmentManager = fm;
            this.mConfiguracoesDeItensDoViewPager = configuracoesDeItensDoViewPager;
        }

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

        @Override
        public Fragment getItem(int indice) {

            Fragment fragmento = null;

            try {
                fragmento = mConfiguracoesDeItensDoViewPager[indice].getClasseDoFragmento().newInstance();
                if (mConfiguracoesDeItensDoViewPager[indice].getArgumentosDoFragmento() != null) {
                    fragmento.setArguments(mConfiguracoesDeItensDoViewPager[indice].getArgumentosDoFragmento());
                }
            } catch (IllegalAccessException e) {
                Log.e(Logs.gerarTagParaFiltragemNoLogCat(AtividadePrincipal.this, this), "Exceção inesperada!", e); 
            } catch (InstantiationException e) {
                Log.e(Logs.gerarTagParaFiltragemNoLogCat(AtividadePrincipal.this, this), "Exceção inesperada!", e); 
            }
            return fragmento;
        }    

        @Override
        public int getCount() {
            return mConfiguracoesDeItensDoViewPager.length;
        }

        @Override
        public CharSequence getPageTitle(int posicao) {
           return mConfiguracoesDeItensDoViewPager[posicao].getNomeDaAba();
        }

        public void setConfiguracoesParaInicializarViewPager(ConfiguracoesDeItemDoViewPager [] configuracoes) {
            // Remove um fragmento extra contido dentro do FragmentoB, que se for
            // deixado no FragmentManager causa erro de id duplicado
            FragmentTransaction ft = mFragmentManager.beginTransaction();
            Fragment fragmento = mFragmentManager.findFragmentById(R.id.mapa);
            if (fragmento != null && fragmento instanceof SupportMapFragment) {
                ft.remove(fragmento);
            }
            ft.commit();

            this.mConfiguracoesDeItensDoViewPager = configuracoes;

            notifyDataSetChanged();
        }
    }
}

Only to complete the explanation, when the user clicks on a button on one of the fragments, is called the method AtividadePrincipal.exibirViewPager2() that should update the views/fragments of ViewPager.

Obs.: I also asked in the Soen.

1 answer

0


I found the bug. It was a typo in the original code I was doing CONFIGURACOES_DO_VIEWPAGER_2 point to CONFIGURACOES_DO_VIEWPAGER_1, so that Fragments were recreated but the views did not appear to be changed. I apologize and thank you for your attention.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.