ActionBarSherlock tabs and menu items - android

I have been learning Action Bar, I want the top menu to have Tabs + One Refresh button. So, I have tried to make a simple menu with one button:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("Refresh")
.setIcon(R.drawable.abs__ic_search_api_holo_light)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
return true;
}
And adding tabs:
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(false);
bar.setDisplayShowHomeEnabled(false);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Grades"), FragmentOne.class, null); // many more tabs in same format
However the problem is when the app is in portrait mode, the menu bar goes to a level below. When in Landscape mode it is more acceptable, however it groups them into pull down list. I have read Android's ActionBar but could not find a solution. What is the workaround this? I only want the Tabs to be scrollable to left-right, and refresh button static at right. Do I need to make a layout and inflate it somehow?

This is a known bug, see this conversation: https://groups.google.com/forum/#!topic/actionbarsherlock/wYuKJUdO1vs/discussion
There is also feedback and a little workaround by Jake Wharton himself, but I don't think it will help you a lot (since you want the tabs, not the spinner).
This solution may be more helpful for you: https://stackoverflow.com/a/13828869/1140682

Related

Add drop down list to top action bar when split and top bar is from a layout

I have seen a lot of similar questions to mine, but they all seem to differ in some way that makes them not so helpful.
I have a split action bar in my activity. I have customized the top action bar to display my own view since I wanted to add icons to the top and not show the launcher icon or activity title. I have added a menu with icons which appears at the bottom. Here is the code that does both these things:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basic_fractions);
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
View view = View.inflate(this,R.layout.action_bar_top,null);
actionBar.setCustomView(view, new ActionBar.LayoutParams(Gravity.RIGHT | Gravity.CENTER_VERTICAL));;
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_basic_fractions, menu);
return true;
}
This code produces the effect I wanted - a split menu with some icon buttons at the top (from the layout view) and some at the bottom (from the menu)
However, I want to add a drop down list to the top action bar. I have found ways to do it if I had a menu there instead of a layout view (for example with submenus or actionLayout), but not with this mixed kind of action bar.
An alternative would be if I could add a menu instead of a layout to be in the top action bar since I am not adding anything special, just a few normal menu buttons, but I couldn't find anyway to force them to appear in the top action bar without making it a layout like this.
Thanks for your help.

ActionBar tabs are split stacked, even when there is enough space on the main bar

I am trying to get the Tabs to be on the main ActionBar, like they show on the Android Developers site
I wrote this basic code:
package com.example.test;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends Activity implements ActionBar.TabListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab = actionBar.newTab().setTabListener(this).setText("TAB LEFT");
actionBar.addTab(tab);
tab = actionBar.newTab().setTabListener(this).setText("TAB CENTER");
actionBar.addTab(tab);
tab = actionBar.newTab().setTabListener(this).setText("TAB RIGHT");
actionBar.addTab(tab);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {}
}
But it shows this instead (tabs are split into a stacked action bar):
The site states:
...the system adapts the action bar tabs for different screen
sizes—placing them in the main action bar when the screen is
sufficiently wide, or in a separate bar (known as the "stacked action
bar") when the screen is too narrow, as shown in figures 9 and 10.
I think the screen is sufficiently wide to put the whole action bar on the main bar. I event tried defining only one tab but it still gets its own stacked bar.
I have the API Demos, but I haven't been able to locate the "Honeycomb Gallery" sample they mention, so I can examine their code.
I also tried to set the ActionBar navigation mode to STANDARD and LIST, but to no avail.
It appears that the Action Bar tab policy changed last year to ALWAYS stack the tabs for ALL screen sizes in portrait mode (and before one knee-jerks why it is working otherwise for them, please read further!) even if it may fit in the Action Bar. This doesn't seem to have been well documented (or documented at all that I can find). I can confirm that this new policy is definitely being applied in JB devices if the target API version is JB.
Found this in the commit notes of the source tree
ActionBar tabs policy commit comments in source tree
Action bar tabs now stack in portrait mode on all screen sizes rather
than display embedded. This only affects apps with a targetSdkVersion
of JB or greater, as older apps may not be prepared for the different
measurement of the bar or have an appropriate stacked bar background
drawable.
Stacked action bar tabs now have a width limit. This prevents
super-wide tabs that can span the whole screen. The cluster of tabs
is centered if it does not span the full width.
So if you must have the tabs embedded in the Action Bar when it fits in the portrait mode, then it appears you would have to make the target API version less than JB (which means the app cannot use any JB or later APIs) or deal with the stacked layout as the only option in portrait mode on any device regardless of the required width for the tabs.
There is a fairly straightforward (well, less hackish) way now. You need to use the appcompat-v7 and design libraries (version 22.0+). I assume you use a ViewPager for the tab contents (if not, simply leave out the ViewPager-related stuff in the code below and replace it with your own tab switching logic). Have your activity extend AppCompatActivity (it has both the support ActionBar and the ViewPager functionality built in), then do the following in its onCreate() method:
ActionBar actionBar = getSupportActionBar();
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
Context ctx = new ContextThemeWrapper(getApplication(), R.style.AppTheme);
mTabLayout = new TabLayout(ctx);
LinearLayout.LayoutParams mTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
mTabLayout.setLayoutParams(mTabLayoutParams);
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
TabLayout.Tab newTab = mTabLayout.newTab();
// Assuming you use icons on tabs (text should work, too)
newTab.setIcon(mSectionsPagerAdapter.getPageIcon(i));
mTabLayout.addTab(newTab);
}
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(mTabLayout);
// This will keep tabs and the ViewPager in sync
// (selecting a tab will switch pages, swiping will update tabs)
mTabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
This works by instantiating a TabLayout() and adding it to the ActionBar as a custom view.
As far as I can tell, this will hide the app icon and title. I haven't yet figured out how to show them if you decide you need them, but I suppose you could always create a LinearLayout, drop the TabLayout and anything else you want on it, and pass this as the custom view.

Tabs on action collapse because the title takes too much room. What can I do?

Because of my long app name (and other factors) the 4 tabs that I have are now collapsed. This happens on devices using large-layout. In portrait mode, it looks like the picture above. However, in landscape mode, there is plenty of room for the name and 4 tabs.
I already tried deleting the title but the tabs are still collapsed. How do I make it so that the tabs always show and if there is no room, have it hide the app name. I'd rather not have ellipses (App Name Go...). I'd rather just hide the title completely. I need this specifically for large-layout in portrait mode.
Any help would be appreciated.
To avoid this, fisrt add tabs after that set navigation mode. Like this,
ActionBar bar = getSupportActionBar();
//dont set navigation mode now.
bar.setLogo(logo);
bar.setHomeButtonEnabled(false);
bar.setDisplayHomeAsUpEnabled(true);
bar.setDisplayShowTitleEnabled(false);
// Now add tabs
ActionBar.Tab tab1 = bar.newTab();
ActionBar.Tab tab2 = bar.newTab();
ActionBar.Tab tab3 = bar.newTab();
tab1.setText("Packages");
tab1.setIcon(R.drawable.abs__ic_menu_share_holo_dark);
tab2.setText("Blogs");
tab2.setIcon(R.drawable.abs__ic_voice_search);
tab3.setText("Gallery");
tab3.setIcon(R.drawable.abs__ic_cab_done_holo_dark);
tab1.setTabListener(new MyTabListener());
tab2.setTabListener(new MyTabListener());
tab3.setTabListener(new MyTabListener());
bar.addTab(tab1);
bar.addTab(tab2);
bar.addTab(tab3);
// Now set navigation mode
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
You do not control when action bar tabs are collapsed. That is up to Android. I filed an issue about this that was rejected.
If you absolutely cannot have the collapsed UI, switch to a ViewPager and either PagerTabStrip, the tab indicator from ViewPagerIndicator, or any other ViewPager tab implementation.
Action Bar will collapse tabs by default when area available is less. In portrait view, it creates another tab panel below the Action Bar. You can force this behavior in landscape mode also:
try {
Class c = Class.forName("com.android.internal.app.ActionBarImpl");
Method m = c.getDeclaredMethod("setHasEmbeddedTabs",boolean.class);
m.setAccessible(true);
m.invoke(getActionBar(),false); //-- do not embed tabs --
}catch (Exception e) {
e.printStackTrace();
}
Note: This is a reflection hack, and underlying private class can change in future versions.

Android - How to get rid of the bar above the ActionBar

EDIT: Android-Developers answer below explains solution very well
My problem is there are another bar, not exactly sure what it's name is - TitleBar? (The bar with the menu button and the white square logo) Above my ActionBar. What I ideally want is to merge my ActionBar with that bar or if not possible, implement my own bar completely amongst the tabs with icon and menu button. I have tried several things (see below image) and the rough code of how I am add the tabs is shown below as well.
Adding tabs to the ActionBar code:
actionBar = getActionBar(); // Get reference to ActionBar
// Add some navigation tabs...
// 1. Enable ActionBar navigation tabs
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
// 2. Add the tabs
Tab programTab = actionBar.newTab();
Tab settingsTab = actionBar.newTab();
Tab historyTab = actionBar.newTab();
programTab.setText("Program")
.setTabListener(new TabListener<Fragment_Program>(
this, "Program", Fragment_Program.class));
settingsTab.setText("Settings")
.setTabListener(new TabListener<Fragment_Settings>(
this, "Settings", Fragment_Settings.class));
historyTab.setText("History")
.setTabListener(new TabListener<Fragment_History>(
this, "History", Fragment_History.class));
actionBar.addTab(programTab);
actionBar.addTab(settingsTab);
actionBar.addTab(historyTab);
I was under the impression getActionBar() got reference to the existing bar which sits above my ActionBar in the screenshot.. that would be ideal.
Current application theme is android:theme="#android:style/Theme.Holo.Light.DarkActionBar"
Anyway, I have tried the following:
Various manifest changes including various .NoTitleBar combinations
requestWindowFeature(Window.FEATURE_NO_TITLE); after super.onCreate() and before setContentView()
The reason I am using standard ActionBar is this for a hardware device that will be running at least 4.0 and the version is highly unlikely to change.
Any thoughts?
Cheers
As I can understand you want to remove that view right?
The problem is that it your ActionBar. I guess you want to use Tabs, but without the ActionBar like many of the apps which are doing that. To achieve this use :
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(false);
bar.setDisplayShowHomeEnabled(false);
But don't forget something, if you want to achieve this, you should not inflate any menu in your Fragment / Activity :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//getSupportMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
You should see #ColorWP answer here
The Window flags are set already set inside super.onCreate(savedInstanceState); in which case you may want to use the following order of commands:
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);

Showing all tabs in action bar sherlock?

Im using action bar sherlock and in landscape mode all of my tabs show, but in portrait only one shows.
How can I show all tabs so the user can slide along them? They dont have to be on screen at the same time, I just dont want a pop up menu.
A bit old question and you may already figured out how to fix it, but here's a solution for people struggling (like I was) with the same issue. In fact, the documentation says the following:
Note: In some cases, the Android system will show your action bar tabs as a drop-down list in order to ensure the best fit in the action bar.
To avoid the drop-down list when your tab items don't fit the screen, add your tabs to ActionBar and set navigation mode after adding the items.
ActionBar bar = getSupportActionBar();
//bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Don't set navigation mode yet, if you do then portrait mode will revert to list mode if tab items don't fit the screen
bar.setLogo(logo);
bar.setHomeButtonEnabled(false);
bar.setDisplayHomeAsUpEnabled(true);
bar.setDisplayShowTitleEnabled(false);
// Add lots of tab items
for (int i = 0; i < channels.length; i++) {
ActionBar.Tab tab = bar.newTab();
String[] s = channels[i].split(":");
tab.setText(s[0]);
tab.setTag(s[1]);
tab.setTabListener(this);
bar.addTab(tab);
}
// Set navigation mode now, that will show all tabs in portrait mode instead of drop-down regardless the screen size
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
That's it :)

Categories

Resources