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.