Mam następujący problem. Mam Activity, które posiada swoje ActionBar. W metodzie onCreate wypełniam programistycznie actionbara w ten sposób:
protected void onCreate(Bundle savedInstanceState) {
//...some other things
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
Tab tab = bar.newTab().setText(R.string.tab_sites).setTabListener(
new TabListener<CategoriesFragment>(activity,"tag1",CategoriesFragment.class));
bar.addTab(tab);
tab = bar.newTab().setText(R.string.tab_offline).setTabListener(
new TabListener<OfflineFragment>(activity,"tag2", OfflineFragment.class));
bar.addTab(tab);
}
CategoriesFragment to ListFragment, nie posiada żadnego xml’a związanego z layoutem. OfflineFragment to Fragment, który buduje swój widok na podstawie xml’a z layoutem (tzn, inflater.inflate(...))
TabListener, z którego korzystam, wygląda tak:
public class TabListener<T extends Fragment> implements
android.app.ActionBar.TabListener {
public MyFragmentListener(Activity activity, String tag, Class<T> tClass) {
this(activity, tag, tClass, null);
}
public MyFragmentListener(Activity activity, String tag, Class<T> tClass,
Bundle bundle) {
this.activity = activity;
this.tag = tag;
this.tClass = tClass;
this.bundle = bundle;
fragment = activity.getFragmentManager().findFragmentByTag(tag);
if(fragment != null && !fragment.isDetached()){
FragmentTransaction fragmentTransaction = activity.getFragmentManager().beginTransaction();
fragmentTransaction.detach(fragment);
fragmentTransaction.commit();
}
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(fragment == null){
fragment = Fragment.instantiate(activity, tClass.getName(),bundle);
ft.add(android.R.id.content,fragment, tag);
} else{
ft.attach(fragment);
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if(fragment != null){
ft.detach(fragment);
}
}
}
Próbuję to odpalić i przetestować. Kiedy Activity startuje, widzę obie taby, które wyglądają tak jak ja chcę:
Tutaj jest pierwszy tab: pierwszy tab
Tutaj jest drugi tab: drugi tab
Kiedy chcę wybrać fragment z listy na pierwszym tabie, chcę zpushować nowy ListFragment w taki oto sposób:
public void onListItemClick(ListView l, View v, int position, long id) {
Bundle bundle = new Bundle();
bundle.putString("chosen", category[position]);
Fragment fragment = new SubcategoryFragment();
fragment.setArguments(bundle);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(getId(), fragment);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack("category_to_subcategory");
fragmentTransaction.commit();
}
Po wybraniu jakiegoś elementu, taby wyglądają tak:
Pierwszy tab: pierwszy tab , czyli tak jak ja chcę, wszystko ok
Drugi tab: drugi tab , no i widać problem - z jakiegoś powodu ta lista z pierwszego taba ‘pojawiła się’ w drugim tabie.
Jeżeli próbuję wcisnąć ‘powrót’ w pierwszym tabie po pojawieniu się nowej listy, powraca do poprzedniej, czyli tak jak ja chcę.
Jeżeli po wybraniu jakiegoś elementu z listy, pojawieniu się nowego listfragmentu, przejdę do drugiego taba, i tam wcisnę powrót, lista z pierwszego taba kompletnie znika: imgur: the simple image sharer
Jeżeli po wybraniu jakiegoś elementu z listy, pojawieniu się nowego listfragmentu, przejdę do drugiego taba, przejdę z powrotem do 1go taba, i tam wcisnę powrót, program się wysypuje, a powodem jest:
06-15 20:11:12.151: E/AndroidRuntime(18971): java.lang.IllegalStateException: Fragment already added: CategoriesFragment{414d9350 #0 id=0x1020002 fanfictionnet_categories}
Jak widać, coś robię źle. Co dokładniej?