Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to always display ActionBar tabs below ActionBar in Android

I have been looking to see if there is any information on how to always display the ActionBar tabs below the ActionBar even when the phone is orientated to landscape. I know that automatically it places the tabs in the ActionBar depending on whether there is enough room on the screen to fit them, but I want them to always be fixed underneath the ActionBar even in landscape. I found a similar question which didn't have a definitive answer: How to display tabs below action bar. I also know that many Google applications, such as; Google Play, Google Music etc implement this type of design pattern, so it is obviously achievable and acceptable as a design pattern.

I am currently using the ActionBarSherlock library to create my sliding tabs navigation and I would really appreciate it if anyone has figured out how to do this themselves. Thanks in advance.

Here is my activity code:

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    viewPager = new ViewPager(this);
    viewPager.setId(R.id.pager);
    setContentView(viewPager);

    tabsAdapter = new TabsAdapter(this, viewPager); // Declares the tabs adapter class with the view pager view

    actionBarTabs = getSupportActionBar();
    actionBarTabs.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBarTabs.setCustomView(spinnerView);
    actionBarTabs.setDisplayShowCustomEnabled(true);    

    /* Adds fragments to the tabs adapter */
    tabsAdapter.addTab(actionBarTabs.newTab().setText("FRAG1"), Fragment_1.class, null);
    tabsAdapter.addTab(actionBarTabs.newTab().setText("FRAG2"), Fragment_2.class, null);
    tabsAdapter.addTab(actionBarTabs.newTab().setText("FRAG3"), Fragment_3.class, null);
}

And here is my TabsAdapter code:

public class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener , ViewPager.OnPageChangeListener 
{
private final Context context;
private final ActionBar actionBar;
private final ViewPager viewPager;
private final ArrayList<TabInfo> tabsList = new ArrayList<TabInfo>();

/**
 * TabInfo class
 * 
 * Static class containing the tab information.
 * 
 * @since 1.0
 */
static final class TabInfo
{
    private final Class<?> clss;
    private final Bundle args;

    TabInfo(Class<?> _class, Bundle _args)
    {
        clss = _class;
        args = _args;
    }
}

/**
 * Tabs adapter overload constructor.
 * 
 * @param fragmentActivity sets the fragment activity to the adapter.
 * @param refViewPager sets the viewPager variable.
 * @see
 * @since 1.0
 */
public TabsAdapter(SherlockFragmentActivity fragmentActivity, ViewPager refViewPager) 
{
    super(fragmentActivity.getSupportFragmentManager());
    context = fragmentActivity;
    actionBar = fragmentActivity.getSupportActionBar();
    viewPager = refViewPager;
    viewPager.setAdapter(this);
    viewPager.setOnPageChangeListener(this);
}

/**
 * Add tab method to add a tab to the list.
 * 
 * @param tab sets the tab to be added to the tabs in the action bar.
 * @param clss sets the class variable in the TabInfo class.
 * @param args sets the bundle variable in the TabInfo class.
 * @see
 * @since 1.0
 */
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args)
{
    TabInfo info = new TabInfo(clss, args);
    tab.setTag(info);
    tab.setTabListener(this);
    tabsList.add(info);
    actionBar.addTab(tab);
    notifyDataSetChanged();
}

@Override
public void onPageScrollStateChanged(int state) 
{

}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) 
{

}

@Override
public void onPageSelected(int position) 
{
    actionBar.setSelectedNavigationItem(position);
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) 
{
    viewPager.setCurrentItem(tab.getPosition());
    Object tag = tab.getTag();
    for (int i = 0; i<tabsList.size(); i++)
    {
        if (tabsList.get(i) == tag)
        {
            viewPager.setCurrentItem(i);
        }
    }

}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) 
{

}

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) 
{

}

@Override
public Fragment getItem(int position) 
{
    TabInfo info = tabsList.get(position);
    return Fragment.instantiate(context, info.clss.getName(), info.args);
}

@Override
public int getCount() 
{
    return tabsList.size();
}
}
like image 967
James Meade Avatar asked Feb 18 '14 09:02

James Meade


People also ask

What is window action bar in Android?

The ActionBar, now known as the App Bar, is a consistent navigation element that is standard throughout modern Android applications. The ActionBar can consist of: An application icon. An "upward" navigation to logical parent. An application or activity-specific title.

How to add action bar in fragment Android?

To do so, you first have to call setHasOptionsMenu() within the fragment's onCreate() method: setHasOptionsMenu(true); Now your fragments menu items will be displayed in the ActionBar. Of course, if you do so, you have to stop using the same entries in your Activity.

What's action bar?

The app bar, also known as the action bar, is one of the most important design elements in your app's activities, because it provides a visual structure and interactive elements that are familiar to users.


1 Answers

I had same issues with landscape mode and I found the solution here: http://andreimihu.com/blog/2013/10/17/android-always-embed-tabs-in-actionbar/

Basically, the writer wants the tab inside actionbar while you and I wants it outside. So, just change the method call to false (code from the above link, but a bit modified):

// This is where the magic happens!
public void forceTabs() {
    try {
        final ActionBar actionBar = getActionBar();
        final Method setHasEmbeddedTabsMethod = actionBar.getClass()
            .getDeclaredMethod("setHasEmbeddedTabs", boolean.class);
        setHasEmbeddedTabsMethod.setAccessible(true);
        setHasEmbeddedTabsMethod.invoke(actionBar, false);
    }
    catch(final Exception e) {
        // Handle issues as needed: log, warn user, fallback etc
        // This error is safe to ignore, standard tabs will appear.
    }
}
like image 62
John Pang Avatar answered Sep 19 '22 03:09

John Pang