I have noticed that when using
actionBar.setSelectedNavigationItem(x)
in the onCreate() method of my Activity, the tab item at position 0 is always selected first and then the tab item at position x is loaded. This means that (since I'm using Fragments) 2 Fragments are loaded. One of them being unnecessary...
Here's my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Determine which bundle to use; either the saved instance or a bundle
// that has been passed in through an intent.
Bundle bundle = getIntent().getExtras();
if (bundle == null) {
bundle = savedInstanceState;
}
// Initialize members with bundle or default values.
int position;
if (bundle != null) {
position = bundle.getInt("selected_tab");
} else {
position = 0;
}
// Set the tabs.
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab = actionBar
.newTab()
.setText("Tab 1")
.setTabListener(
new TabListener<RendersGridFragment>(this, "1",
RendersGridFragment.class));
actionBar.addTab(tab);
tab = actionBar
.newTab()
.setText("Tab 2")
.setTabListener(
new TabListener<RendersGridFragment>(this, "2",
RendersGridFragment.class));
actionBar.addTab(tab);
tab = actionBar
.newTab()
.setText("Tab 3")
.setTabListener(
new TabListener<RendersGridFragment>(this, "3",
RendersGridFragment.class));
actionBar.addTab(tab);
actionBar.setSelectedNavigationItem(position);
}
It seems that the tab at position 0 is selected initially by default. But, as you can see, I'm passing bundles to make sure the last selected tab is still selected when the activity onCreate() method is run again.
For example,
if the last selected tab is at position 2, the onCreate() runs and the tab at position is 0 is loaded, then the tab at position 2 is loaded.
How can I make sure the ActionBar doesn't select tab at position 0 first when using actionBar.setSelectedNavigationItem(position).
Use the other addTab calls to override this behaviour. You'll need to add the tab you want to be selected first (in your case, the tab at position 2). Relevant Javadoc
actionBar.addTab(tab2);
actionBar.addTab(tab0, 0, false);
actionBar.addTab(tab1, 1, false);
For any others looking to do this you can also set the tab to selected by setting the position and then set true or false to indicate which tab should be selected
actionBar.addTab(tab1, 0, false);
actionBar.addTab(tab2, 1, true);
actionBar.addTab(tab3, 2, false);
Here are the docs on this approach: http://developer.android.com/reference/android/app/ActionBar.html#addTab(android.app.ActionBar.Tab, int, boolean)
you can use below statment in activtiy onStart method:
protected void onStart() {
super.onStart();
actionBar.selectTab(mainTab);
}
which mainTab variable here is of type Tab.
this way you need to define tabs as class-wide variables like this:
Tab mainTab, tab2,tab3;
#Override
protected void onCreate(Bundle savedInstanceState) {
//add tabs to action bar
....
}
If you have 3 tabs (i.e. tab 0, tab 1, tab 2) and want tab 1 to be preselected. Do this:
for (int i = 0; i < mFragmentPagerAdapter.getCount(); i++) {
boolean preselected = (i == 1);
actionBar.addTab(actionBar.newTab().setText(
mFragmentPagerAdapter.getPageTitle(i)).setTabListener(this), preselected);
}
You will be using:
public abstract void addTab (ActionBar.Tab tab, boolean setSelected)
as per this API specification.
bkurzius' answer helped me to fix a problem I was having with the same issue.
What I did was:
private final String TAB_SELECTED = "tab_selected"
...
private int mTabSelected;
...
mTabSelected = savedInstanceState.getInt(TAB_SELECTED);
...
final ActionBar actionbar = getActionBar();
...
actionbar.addTab(tab1, mTabSelected == 0);
actionbar.addTab(tab2, mTabSelected == 1);
actionbar.addTab(tab3, mTabSelected == 2);
...
outState.putInt(TAB_SELECTED, getActionBar().getSelectedNavigationIndex());
This way, the setSelected parameter is true only if mTabSelected is equal to the tab's index.
Percy Vega's reply seems to be the best working solution.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
boolean preselected = (i == ErrorDetails.tab_id);
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this),preselected);
}
Related
I am trying to set custom colors for my tabs in android programmatically. Unselected color - black. Selected color - white. But only the first tab remains selected because of
tabHost.getTabWidget().getChildAt(0).setBackgroundColor(Color.parseColor("#FFFFFF"));
But the remaining tabs when selected do not change color. I do not know what I am missing. Here is what I have:
TabHost tabhost;
public void onCreate(Bundle savedInstanceState) {
tabHost = getTabHost();
.... // remaining definition of tabs go here
for(int i=0; i < tabHost.getTabWidget().getChildCount();i++)
{
tabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#000000"));
}
//tabHost.getTabWidget().setCurrentTab(0);
tabHost.getTabWidget().getChildAt(0).setBackgroundColor(Color.parseColor("#FFFFFF"));
} // close of oncreate() function
public void onTabChanged(String tabId) {
for(int i=0; i < tabHost.getTabWidget().getChildCount(); i++)
{
tabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#000000")); //inactive tabs
}
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundColor(Color.parseColor("#FFFFFF")); //active tab
}
}
Change your last line in:
tabHost.getCurrentTabView().setBackgroundColor(Color.parseColor("#FFFFFF")); //active tab
I want to change color of text in tabs. How can I reference the tab layout in which I want to change color property inside of the function:
public void onConfigurationChanged(Configuration newConfig)
{
findViewById(R.id.tab_textview); // returns null
}
Since this returns null. tab_textview is the template for the tab. In the onCreate I just put tabs inside the actionbar and everything works. I just need to change color when orientation is changed so the text is white and visible. Find many similar problems but I cant get it to work. I am very new to android programming.
At the onCreate method, we initial the ActionBar like this:
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab = actionBar
.newTab()
.setCustomView(R.layout.tab_textview) // use our TextView
.setTabListener(
new Chapter1TabListener<FragmentA>(this, "fragmentA",
FragmentA.class));
TextView tabview = (TextView) tab.getCustomView();
tabview.setText("First Tab");
actionBar.addTab(tab);
tab = actionBar
.newTab()
.setCustomView(R.layout.tab_textview)
.setTabListener(
new Chapter1TabListener<FragmentB>(this, "fragmentB",
FragmentB.class));
tabview = (TextView) tab.getCustomView();
tabview.setText("Second Tab");
actionBar.addTab(tab);
Override onConfigurationChanged, try as following:
super.onConfigurationChanged(newConfig);
if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
ActionBar actionBar = getActionBar();
for(int i=0; i<actionBar.getTabCount(); i++ ) {
Tab tab = actionBar.getTabAt(i);
TextView tv = (TextView) tab.getCustomView();
tv.setTextColor(getResources().getColor(android.R.color.holo_blue_dark));
}
}
I have an activity with two fragments added to a tabAction. The first one is the gridview of applications, the second one is a gridview for documents. When I rotate the tablet my fragments are not up to date. I would like to instantiate my fragment after a rotation so the Activity restarts; but the problem that I don't use viewpager. And with the part of code given below:
// ActionBar
actionbar = getActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setDisplayUseLogoEnabled(false);
actionbar.setDisplayShowTitleEnabled(false);
// create new tabs and set up the titles of the tabs
ActionBar.Tab mFindTab = actionbar.newTab().setText(
getString(R.string.ui_tabname_find));
ActionBar.Tab mChatTab = actionbar.newTab().setText(
getString(R.string.ui_tabname_chat));
ActionBar.Tab mMeetTab = actionbar.newTab().setText(
getString(R.string.ui_tabname_meet));
ActionBar.Tab mPartyTab = actionbar.newTab().setText(
getString(R.string.ui_tabname_find));
// create the fragments
Fragment mMeetFragment = new ApplicatinFragment();
Fragment mFindFragment = new MatFragment();
Fragment mChatFragment = new DocumentFragment1();
Fragment mPartyFragment = new PartyFragment();
// bind the fragments to the tabs - set up tabListeners for each tab
mFindTab.setTabListener(new MyTabsListener(mFindFragment,
this.getBaseContext()));
mChatTab.setTabListener(new MyTabsListener(mChatFragment,
getApplicationContext()));
mMeetTab.setTabListener(new MyTabsListener(mMeetFragment,
getApplicationContext()));
actionbar.addTab(mMeetTab);
actionbar.addTab(mFindTab);
my onSaveInstanceState is given by the code below:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
/*
Toast.makeText(
this,
"onSaveInstanceState: tab is"
+ getActionBar().getSelectedNavigationIndex(),
Toast.LENGTH_SHORT).show(); */
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
outState.putStringArrayList("List", LaunchActivity.myList);
outState.putString("ListActivity", LaunchActivity.myList.toString());
}
then in my Oncreat I call :
if (savedInstanceState != null) {
savedUser = savedInstanceState.getString("TEXT");
savedMode = savedInstanceState.getString("MODE");
String str;
str = savedInstanceState.getString("ListActivity");
test = savedInstanceState.getStringArrayList("List");
//actionbar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 1));
// myList = (ArrayList<String>) Arrays.asList(str.split("\\s*,\\s*"));
actionbar.setSelectedNavigationItem(savedInstanceState.getInt(
TAB_KEY_INDEX, 0));
} else {
savedUser = "eleve";
savedMode = "normal";
}
I would like to use the solution given in what's the right way to store fragment's state
ViewPager and fragments — what's the right way to store fragment's state ]1
I am using Actionbarsherlock for tab layout. In some conditions I want to set the tab at index 4 as the default tab. I mean the tab should stay at 5th position but it should be the default one. Is there any way to do that?
My class definition looks like this:
public class CalendarActivity extends SherlockFragmentActivity implements ActionBar.TabListener
and the onCreate method looks like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabMonthly = bar.newTab();
tabMonthly.setText("Monthly").setTabListener(this);
bar.addTab(tabMonthly);
ActionBar.Tab tabWeekly = bar.newTab();
tabWeekly.setText("Weekly").setTabListener(this);
bar.addTab(tabWeekly);
ActionBar.Tab tabDaily = bar.newTab();
tabDaily.setText("Day").setTabListener(this);
bar.addTab(tabDaily);
ActionBar.Tab tabList = bar.newTab();
tabList.setText("List").setTabListener(this);
bar.addTab(tabList);
ActionBar.Tab addEvent = bar.newTab();
addEvent.setText("Unread").setTabListener(this);
bar.addTab(addEvent);
//String callerActivity = getIntent().getStringExtra("activityCaller");
//if( callerActivity!= null && callerActivity.equalsIgnoreCase("notification") ){
//bar.setSelectedNavigationItem(4);
//}
}
I tried the code commented at the end of onCreate() method above. But the problem with this code is that it first loads the tab at index zero and then suddenly goes to tab at index4.
I have an ActionBar with multiple tabs, each linked to a fragment. The problem I have is that when I use either bar.selectTab(Tab) or bar.setSelectedNavigationItem(int), it doesn't work. Specifically, this problem occurs when the tabs get reduced down to a Spinner in the ActionBar.
There is a known bug with the ActionBar, specifically with the methods mentioned above and specifically when the ActionBar's tabs are reduced to a Spinner.
Here's my workaround. It uses reflection to drill into the ActionBar if the tabs have been reduced to a Spinner. In your Activity class, create a method like so:
/**
* A documented and yet to be fixed bug exists in Android whereby
* if you attempt to set the selected tab of an action bar when the
* bar's tabs have been collapsed into a Spinner due to screen
* real-estate, the spinner item representing the tab may not get
* selected. This bug fix uses reflection to drill into the ActionBar
* and manually select the correct Spinner item
*/
private void select_tab(ActionBar b, int pos) {
try {
//do the normal tab selection in case all tabs are visible
b.setSelectedNavigationItem(pos);
//now use reflection to select the correct Spinner if
// the bar's tabs have been reduced to a Spinner
View action_bar_view = findViewById(getResources().getIdentifier("action_bar", "id", "android"));
Class<?> action_bar_class = action_bar_view.getClass();
Field tab_scroll_view_prop = action_bar_class.getDeclaredField("mTabScrollView");
tab_scroll_view_prop.setAccessible(true);
//get the value of mTabScrollView in our action bar
Object tab_scroll_view = tab_scroll_view_prop.get(action_bar_view);
if (tab_scroll_view == null) return;
Field spinner_prop = tab_scroll_view.getClass().getDeclaredField("mTabSpinner");
spinner_prop.setAccessible(true);
//get the value of mTabSpinner in our scroll view
Object tab_spinner = spinner_prop.get(tab_scroll_view);
if (tab_spinner == null) return;
Method set_selection_method = tab_spinner.getClass().getSuperclass().getDeclaredMethod("setSelection", Integer.TYPE, Boolean.TYPE);
set_selection_method.invoke(tab_spinner, pos, true);
} catch (Exception e) {
e.printStackTrace();
}
}
Example usage of this might be:
private void delete_fragment_and_tab(String fragment_tag) {
//remove the fragment
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(getFragmentManager().findFragmentByTag(fragment_tag));
//now remove the tab from the ActionBar
//and select the previous tab
ActionBar b = getActionBar();
Tab tab = b.getSelectedTab();
bar.removeTab(tab);
select_tab(bar, bar.getNavigationItemCount() -1);
}