I have 3 fragments and an activity. I want to enable tabs on the ActionBar
and assign a Fragment
to each of the 3 tabs. How do I hook that up correctly?
ORIGINAL POST
I have an app that I'm developing using the Google I/O app as a guide. I've implemented tabs into the ActionBar
. They seem to be working until the tablet's orientation changes. For example, all 3 tabs have a Fragment
. I can switch between them just fine, but when I change the orientation, whatever the Fragment
I was last viewing stays visible, but clicking the tabs no longer changes the view... like they have become disconnected. As expected, going back to the original orientation does not "fix" it.
I've looked into saving and restoring state, but I'm not seeing how those would help.
EDIT
module level:
Fragment mFragmentA = (Fragment) new AFragmentTab();
Fragment mFragmentB = (Fragment) new BFragmentTab();
Fragment mFragmentC = (Fragment) new CFragmentTab();
I have something like this in the activity's onCreate
:
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
ActionBar.Tab tabA = actionBar.newTab().setText("text a");
ActionBar.Tab tabB = actionBar.newTab().setText("text b");
ActionBar.Tab tabC = actionBar.newTab().setText("text c");
tabA.setTabListener(this);
tabB.setTabListener(this);
tabC.setTabListener(this);
actionBar.addTab(tabA);
actionBar.addTab(tabB);
actionBar.addTab(tabC);
and a TabListener
like this:
EDIT this is removed
class MyTabListener implements ActionBar.TabListener {
private Fragment mFragment;
// Called to create an instance of the listener when adding a new tab
public MyTabListener(Fragment fragment) {
mFragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_content, mFragment, null);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// do nothing
}
}
EDIT
I've moved the TabListener
. Instead of it being a separate class, I implement the TabListener
on the Activity
. Then on the Selected
and Unselected
methods I have something like:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
ft.add(R.id.fragment_content, mFragmentA, null);
break;
case 1:
ft.add(R.id.fragment_content, mFragmentB, null);
break;
case 2:
ft.add(R.id.fragment_content, mFragmentC, null);
break;
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
ft.remove(mFragmentA);
break;
case 1:
ft.remove(mFragmentB);
break;
case 2:
ft.remove(mFragmentC);
break;
}
}
It's still doing the same thing. I really don't know what's happening.
It looks like my answer can be found here: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.html
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
import com.example.android.apis.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.Toast;
/**
* This demonstrates the use of action bar tabs and how they interact
* with other action bar features.
*/
public class FragmentTabs extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.addTab(bar.newTab()
.setText("Simple")
.setTabListener(new TabListener<FragmentStack.CountingFragment>(
this, "simple", FragmentStack.CountingFragment.class)));
bar.addTab(bar.newTab()
.setText("Contacts")
.setTabListener(new TabListener<LoaderCursor.CursorLoaderListFragment>(
this, "contacts", LoaderCursor.CursorLoaderListFragment.class)));
bar.addTab(bar.newTab()
.setText("Apps")
.setTabListener(new TabListener<LoaderCustom.AppListFragment>(
this, "apps", LoaderCustom.AppListFragment.class)));
bar.addTab(bar.newTab()
.setText("Throttle")
.setTabListener(new TabListener<LoaderThrottle.ThrottledLoaderListFragment>(
this, "throttle", LoaderThrottle.ThrottledLoaderListFragment.class)));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener(Activity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public TabListener(Activity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.hide(mFragment);
ft.commit();
}
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.show(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.hide(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show();
}
}
}