SupportMapFragment view not destroyed when detaching - android

I have a layout with two tabs (fragments) The first tab is a simple ListFragment. The second tab is a fragment that extends SupportMapFragment. When I click on the second tab and then re-click the original tab I have a redraw issue (see screenshot). This does not happen is I use a regular fragment instead of a SupportMapFragment. Here is the code for the parent activity containing the two tabs:
public class MainActivity extends ActionBarActivity {
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Notice that setContentView() is not used, because we use the root
// android.R.id.content as the container for each fragment
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab1 = actionBar.newTab()
.setText(R.string.title_routes_list)
.setTag(R.string.title_routes_list)
.setTabListener(new TabListener<RoutesListFragment>(
this, getString(R.string.title_routes_list), RoutesListFragment.class));
actionBar.addTab(tab1);
Tab tab2 = actionBar.newTab()
.setText(R.string.title_routes_map)
.setTag(R.string.title_routes_map)
.setTabListener(new TabListener<RoutesMapFragment>(
this, getString(R.string.title_routes_map), RoutesMapFragment.class));
actionBar.addTab(tab2);
//GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current tab position.
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getSupportActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Serialize the current tab position.
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getSupportActionBar()
.getSelectedNavigationIndex());
}
private class TabListener<T extends Fragment> implements ActionBar.TabListener {
private final ActionBarActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private Fragment mFragment;
public TabListener(ActionBarActivity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public TabListener(ActionBarActivity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Fragment preInitializedFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if (preInitializedFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), null);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(preInitializedFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Fragment preInitializedFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if (preInitializedFragment != null) {
ft.detach(preInitializedFragment);
} else if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
}

Related

Sherlock tabs not working on orientation change

I managet to set up three tabs using Sherlock ActionBar. The only problem is that when orientation is changed, tabs can not be tapped any more. It seem like the onTabSelected() is not called. Example: I am in portrait and the tab2 is selected. I change into lanscape. Tab2 is still selected, I tap tab3 but nothing happens. Then when I go back to portrait again, tab3 is shown. I am testing in Android 2.3.6.
This is the main activity:
public class Activity_Main extends SherlockFragmentActivity {
ActionBar.Tab tab1, tab2, tab3;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTabs();
}
void setTabs(){
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tab1 = actionBar.newTab();
tab2 = actionBar.newTab();
tab3 = actionBar.newTab();
tab1.setText("Week");
tab2.setText("Today");
tab3.setText("ToDo");
tab1.setTabListener(new TabListener<Fragment_Start_Week>(this, "week", Fragment_Start_Week.class));
tab2.setTabListener(new TabListener<Fragment_Start_Today>(this, "today", Fragment_Start_Today.class));
tab3.setTabListener(new TabListener<Fragment_Start_Todo>(this, "todo", Fragment_Start_Todo.class));
}
private class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener{
private SherlockFragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
/**
* Constructor used each time a new tab is created.
*
* #param activity
* The host Activity, used to instantiate the fragment
* #param tag
* The identifier tag for the fragment
* #param clz
* The fragment's Class, used to instantiate the fragment
*/
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
public void onTabSelected(Tab tab, FragmentTransaction ft) {
SherlockFragment preInitializedFragment = (SherlockFragment) ((FragmentActivity) mActivity).getSupportFragmentManager().findFragmentByTag(mTag);
// Check if the fragment is already initialized
if (mFragment == null && preInitializedFragment == null) {
// If not, instantiate and add it to the activity
mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else if (mFragment != null) {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
} else if (preInitializedFragment != null) {
ft.attach(preInitializedFragment);
mFragment = preInitializedFragment;
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
This is a fragment:
public class Fragment_Start_Week extends SherlockFragment implements OnClickListener{
void create_table() {
...
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
{
return inflater.inflate(R.layout.fragment_start_week, group, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
create_table();
}
#Override
public void onClick(View view) {
...
}
}
TIA
After a lot of trial and errors I've found the following solution for this bug:
#Override
public void onConfigurationChanged(Configuration newConfig) {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
super.onConfigurationChanged(newConfig);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
The trick is to change the navigation mode to list then change back to tabs.

Unable to start activity componentInfo Tablistener suddenly crashing the app

So i'm getting this annoying problem. I'm pretty noob when it comes to android, so any help would be nice.
This is my MainActivity which seems to be crashing according to LogCat.
The app i'm trying to create must pull data from XML data, which i'm trying to get. Then from this data it must set the tabs name (that's what i'm trying to do).
public class MainActivity extends SherlockActivity {
private String uniqeAppId;
private ArrayList<StartupInfo> info;
private String ChannelTab;
private String VicinityTab;
private String CustomTab;
private String TrackingTab;
private String MoreTab;
public static Context appContext;
private DownloadXmlTask downloadxml = new DownloadXmlTask(this);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = new ArrayList<StartupInfo>();
downloadxml.loadPage();
appContext = getApplicationContext();
ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setTitle(uniqeAppId);
ActionBar.Tab Frag1 = actionbar.newTab().setText(ChannelTab);
ActionBar.Tab Frag2 = actionbar.newTab().setText(VicinityTab);
ActionBar.Tab Frag3 = actionbar.newTab().setText(CustomTab);
ActionBar.Tab Frag4 = actionbar.newTab().setText(TrackingTab);
ActionBar.Tab Frag5 = actionbar.newTab().setText(MoreTab);
Fragment Fragment1 = new Channeltab();
Fragment Fragment2 = new Vicinitytab();
Fragment Fragment3 = new Customtab();
Fragment Fragment4 = new Trackingtab();
Fragment Fragment5 = new Moretab();
Frag1.setTabListener(new MyTabListener(Fragment1));
Frag2.setTabListener(new MyTabListener(Fragment2));
Frag3.setTabListener(new MyTabListener(Fragment3));
Frag4.setTabListener(new MyTabListener(Fragment4));
Frag5.setTabListener(new MyTabListener(Fragment5));
actionbar.addTab(Frag1);
actionbar.addTab(Frag2);
actionbar.addTab(Frag3);
actionbar.addTab(Frag4);
actionbar.addTab(Frag5);
}
public void GetTextForTabs(ArrayList<StartupInfo> info2) {
this.info = info2;
StartupInfo info3 = info.get(0);
this.ChannelTab = info3.getChannelTab();
this.VicinityTab = info3.getVicinityTab();
this.CustomTab = info3.getCustomTab();
this.TrackingTab = info3.getTrackingTab();
this.MoreTab = info3.getMoreTab();
}
#Override
public void onStart() {
super.onStart();
}
public void setInfo(ArrayList<StartupInfo> info) {
this.info = info;
}
public void alert(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
public class MyTabListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
}
Then the LogCat:
It seems to be the TabListener. But I don't understand why. It wasn't doing that earlier. It was when i tried to add data it started to crash. Can anyone help me here ?
You have a null pointer exception at line 111 of your activity (in onTabSelected). It looks as though the null reference is probably to "fragment". Look at the section on "Performing fragment transactions":
http://developer.android.com/guide/components/fragments.html
This code will not fit your program exactly, but it gives you the general idea. You need to begin, do your add/replace/why and then commit.
By the by, since you are using ActionBarSherlock why not use the Support library so as to be able to support older versions of Android ?
Here is a simple example (it contains some superfluous stuff that you don't need) that might help:
public class ExtraContent extends SherlockFragmentActivity {
// Declare Tab Variable
com.actionbarsherlock.app.ActionBar.Tab tab;
boolean mDebugLog = false;
String mDebugTag="ian_";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//mDebugLog = true;
debugLog("ExtraContent onCreate" );
// Create the actionbar
com.actionbarsherlock.app.ActionBar bar = getSupportActionBar();
// Show Actionbar Home Icon (as normal)
bar.setDisplayShowHomeEnabled(true);
// Show Actionbar Title (as normal)
bar.setDisplayShowTitleEnabled(true);
// Create Actionbar Tabs
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//enable home ...
bar.setDisplayHomeAsUpEnabled(true); // ?
bar.setHomeButtonEnabled(true); // this is the one that enables home navigation
//ib18 view for fragments ...
setContentView(R.layout.extra_content);
//create the fragment we want to use for display content
Fragment ExtraLogin = new ExtraLogIn();
// Create First Tab
ActionBar.Tab tab0 = bar.newTab();
tab0 = bar.newTab();
tab0.setText("Unlock");
tab0.setTabListener(new TabListener<ExtraTab0>(this, "tab0",ExtraTab0.class, null));
bar.addTab(tab0);
// Create Second Tab
ActionBar.Tab tab1 = bar.newTab();
tab1 = bar.newTab();
tab1.setText("Level 1");
tab1.setTabListener(new TabListener<ExtraTab1>(this, "tab1",ExtraTab1.class, null));
bar.addTab(tab1);
// Create Third Tab
ActionBar.Tab tab2 = bar.newTab();
tab2 = bar.newTab();
tab2.setText("Level 2");
tab2.setTabListener(new TabListener<ExtraTab2>(this, "tab2",ExtraTab2.class, null));
bar.addTab(tab2);
if (savedInstanceState != null) { //if there is a saved bundle use it ...
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
else {
//ib18 savedInstanceState null so fti so start Login frag ...
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.fb, ExtraLogin, "ExtraLogin").commit();
}
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
debugLog("ExtraContent onMenuItemSelected" );
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, QuizLaunch.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
debugLog("ExtraContent onSaveInstanceState");
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}
public class TabListener<T extends Fragment> implements ActionBar.TabListener{
private final FragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener (FragmentActivity activity, String tag, Class<T> clz,
Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
debugLog("ExtraContent TabListener" );
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
// 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.getSupportFragmentManager().findFragmentByTag(mTag);
//
if (mFragment != null && !mFragment.isDetached()) {
ft.detach(mFragment);
}
ft.commit();
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
debugLog("ExtraContent onTabSelected");
ft = mActivity.getSupportFragmentManager()
.beginTransaction();
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(),mArgs);
debugLog("adding fragment "+mTag );
ft.add(R.id.tab, mFragment, mTag); //ib18 add to "tab" holder
ft.show(mFragment); //ib1.6 show fragment ...
ft.commit();
} else {
debugLog("attaching fragment "+mTag );
ft.attach(mFragment);
ft.show(mFragment); //ib1.6 show fragment ...
ft.commit();
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
debugLog("ExtraContent onTabUnSelected");
ft = mActivity.getSupportFragmentManager()
.beginTransaction();
if (mFragment != null) {
debugLog("hide and detach fragment "+mFragment );
ft.hide(mFragment); //ib1.6 hide fragment ...
ft.detach(mFragment);
ft.commitAllowingStateLoss();
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
debugLog("ExtraContent onTabReSelected");
}
}
void debugLog(String message) {
if (mDebugLog)
Log.d(mDebugTag, message);
}
}

how to put an expandable list inside a ActionBar tab fragment?

Hi im a bit noob in android so i hope anyone can help me
i have an actionBar tab fragment, and i wanted to make a expandable list with data and put it on the fragment, i´ve been searching online but the examples are too complex and dont match my situation i just want a simple expandable list, can anyone help?
If I understand you correctly, you should only put ExpandableList inside of your fragment layout for particular layout for actionBar tab fragment. This should be really easy actually...
Can you provide us with some code maybe?
this is my class tabActionBarActivity:
public class TabActionBarActivity extends Activity {
String contextoId;
String BuId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_action_bar);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
String label1 = getResources().getString(R.string.label1);
Tab tab = actionBar.newTab();
tab.setText(label1);
TabListener<Tab1Fragment> tl = new TabListener<Tab1Fragment>(this, label1, Tab1Fragment.class);
tab.setTabListener(tl);
actionBar.addTab(tab);
String label2 = getResources().getString(R.string.label2);
tab = actionBar.newTab();
tab.setText(label2);
TabListener<Tab2Fragment> tl2 = new TabListener<Tab2Fragment>(this, label2, Tab2Fragment.class);
tab.setTabListener(tl2);
actionBar.addTab(tab);
BuId = getIntent().getExtras().getString("BUId");
contextoId = getIntent().getExtras().getString("CId");
Log.i("BUIdTabFrag", BuId);
private class TabListener<T extends Fragment> implements
ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tab_action_bar, menu);
return true;
}
and

Android Actionbar Sherlock with Tabs

I am trying to implement ActionBar Sherlock with Tabs below that as shown in the above wire-frame.
Should i use TabActivity ? - since i saw that it is deprecated. Which is the best way to achieve the same.
I implemented this functionality with a SherlockFragmentActivity as tabview container and with SherlockFragment as tabs. Here is a sketch (I omitted the usual Android activity stuff):
This is the tabview activity with two tabs:
public class TabViewActivity extends SherlockFragmentActivity {
// store the active tab here
public static String ACTIVE_TAB = "activeTab";
#Override
public void onCreate(Bundle savedInstanceState) {
..
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// add the first tab which is an instance of TabFragment1
Tab tab1 = actionBar.newTab()
.setText("TabTitle1")
.setTabListener(new TabListener<TabFragment1>(
this, "tab1", TabFragment1.class));
actionBar.addTab(tab1);
// add the second tab which is an instance of TabFragment2
Tab tab2 = actionBar.newTab()
.setText("TabTitle2")
.setTabListener(new TabListener<TabFragment2>(
this, "tab2", TabFragment2.class));
actionBar.addTab(tab2);
// check if there is a saved state to select active tab
if( savedInstanceState != null ){
getSupportActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(ACTIVE_TAB));
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// save active tab
outState.putInt(ACTIVE_TAB,
getSupportActionBar().getSelectedNavigationIndex());
super.onSaveInstanceState(outState);
}
}
And this is the TabFragment that holds a tab's content:
public class TabFragment extends SherlockFragment {
// your member variables here
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_va_esh, container, false);
... // do your view initialization here
return view;
}
}
And finally this is the TabListener that handles tab switches:
public class TabListener<T extends Fragment> implements ActionBar.TabListener{
private TabFragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = (TabFragment) Fragment.instantiate(
mActivity, mClass.getName());
mFragment.setProviderId(mTag); // id for event provider
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
}
I believe TabActivity is deprecated in favor of using Fragments -- not because tab navigation is a deprecated concept. Simply use Fragments and a TabWidget.
Also, here's a similar question.
Edit:
Here's an example courtesy of Google: Android Tabs the Fragment Way

tab contents using actionbarsherlock tab style

referring to this code below (taken from https://gist.github.com/1126843 ) how do i set the contents of the tabs?
public class NativeTabActivity extends Activity {
private TabHost mTabHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
addTab(new TextView(this), "Tab 1");
addTab(new TextView(this), "Tab 2");
addTab(new TextView(this), "Tab 3");
}
private void addTab(final View content, final String title) {
View tabView = LayoutInflater.from(this).inflate(R.layout.abs__action_bar_tab_layout, null);
TextView tv = (TextView) tabView.findViewById(R.id.abs__tab);
tv.setText(title);
TabSpec setContent = mTabHost.newTabSpec(title).setIndicator(tabView).setContent(new TabContentFactory() {
public View createTabContent(String tag) {
return content;
}
});
mTabHost.addTab(setContent);
}
}
from the code, it seems I need to put the contents under the View createTabContent(String tag) but how do I do it?
I found Rymnel's answer very helpful, but I had to make some changes to get it working properly with ActionBarSherlock 4.0. I was having problems with overriding the onTab methods passing in FragmentTransactions, so I just used the default methods and reassigned the "ft" var inside the method. I'm sure there's a cleaner way to do this, but here is my working code:
public class TabTestActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(true);
bar.setDisplayShowTitleEnabled(true);
bar.setTitle("Activity Title");
bar.addTab(bar
.newTab()
.setText("Tab 1")
.setTabListener(
new TabListener<TabTest1>(this, "tab1",
TabTest1.class, null)));
bar.addTab(bar
.newTab()
.setText("Tab 2")
.setTabListener(
new TabListener<TabTest2>(this, "tab2",
TabTest2.class, null)));
bar.addTab(bar
.newTab()
.setText("Tab 3")
.setTabListener(new TabListener<TabTest3>(this, "tab3", TabTest3.class, null)));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, DashboardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar()
.getSelectedNavigationIndex());
}
public class TabListener<T extends Fragment> implements
ActionBar.TabListener {
private final FragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener(FragmentActivity activity, String tag, Class<T> clz,
Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
FragmentTransaction ft = mActivity.getSupportFragmentManager()
.beginTransaction();
// 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.getSupportFragmentManager()
.findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
ft.detach(mFragment);
}
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft = mActivity.getSupportFragmentManager()
.beginTransaction();
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(),
mArgs);
ft.add(android.R.id.content, mFragment, mTag);
ft.commit();
} else {
ft.attach(mFragment);
ft.commit();
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft = mActivity.getSupportFragmentManager()
.beginTransaction();
if (mFragment != null) {
ft.detach(mFragment);
ft.commitAllowingStateLoss();
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
I use Fragments for my Sherlock implementation.
public class ActionBarTabs extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.addTab(bar.newTab()
.setText("Home")
.setTabListener(new TabListener<DashBoardFragment>(
this, "home", DashBoardFragment.class, null)));
bar.addTab(bar.newTab()
.setText("Inventory")
.setTabListener(new TabListener<InventoryFragment>(
this, "inventory", InventoryFragment.class, null)));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go Location selection
Intent intent = new Intent(ActionBarTabs.this, LocationSelectorActivity.class);
ActionBarTabs.this.startActivityForResult(intent,0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}
public class TabListener<T extends Fragment> implements ActionBar.TabListener {
private final FragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener(FragmentActivity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
// 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.getSupportFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
ft.detach(mFragment);
}
}
#Override
public void onTabSelected(Tab tab) {
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
ft.commit();
} else {
ft.attach(mFragment);
ft.commit();
}
}
#Override
public void onTabUnselected(Tab tab) {
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
if (mFragment != null) {
ft.detach(mFragment);
ft.commitAllowingStateLoss();
}
}
#Override
public void onTabReselected(Tab tab) {
}
}
}
The key change to load different fragments into the tabs is to simply change the "YOUR_FRAGMENT_NAME" to the name of your fragment class in these lines:
bar.addTab(bar.newTab()
.setText("Home")
.setTabListener(new TabListener<YOUR_FRAGMENT_NAME>(
this, "home", YOUR_FRAGMENT_NAME.class, null)));
Hope this helps!

Categories

Resources