Как всегда показывать вкладки ActionBar ниже ActionBar на Android

Я искал, есть ли информация о том, как всегда отображать вкладки ActionBar под ActionBar, даже если телефон ориентирован на пейзаж. Я знаю, что автоматически он помещает вкладки в ActionBar в зависимости от того, достаточно ли места на экране, чтобы соответствовать им, но я хочу, чтобы они всегда фиксировались под ActionBar даже в ландшафте. Я нашел аналогичный вопрос, который не дал окончательного ответа: Как отображать вкладки под панелью действий. Я также знаю, что многие приложения Google, такие как; Google Play, Google Music и т.д. Реализуют этот тип шаблона проектирования, поэтому он явно достижим и приемлем в качестве шаблона проектирования.

В настоящее время я использую библиотеку ActionBarSherlock для создания моей скользящей навигации вкладок, и я был бы очень признателен, если бы кто-нибудь понял, как это сделать. Спасибо заранее.

Вот мой код активности:

@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);
}

И вот мой код TabsAdapter:

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();
}
}

Ответы

Ответ 1

У меня были такие же проблемы с ландшафтным режимом, и я нашел решение здесь: http://andreimihu.com/blog/2013/10/17/android-always-embed-tabs-in-actionbar/

В принципе, сценаристу требуется вкладка внутри панели действий, в то время как вы и я хотим ее снаружи. Итак, просто измените вызов метода на false (код из приведенной выше ссылки, но немного изменен):

// 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.
    }
}

Ответ 2

Во-первых, то, что вы описываете как "многие приложения Google, такие как Google Play, Google Music и т.д., реализует этот тип шаблона проектирования", не обязательно являются навигационными вкладками, связанными с ActionBar.

Существует множество реализаций, которые используют viewPager с индикатором заголовка. Для хорошей реализации обратитесь к библиотеке PagerSlidingTabStrip.

Кроме того, вы должны проверить официальную документацию по Android, где она подробно рассказывает о навигации с вкладками и показывает различные способы ее получения. Проверьте эти страницы в документации: Предоставление потоковой и боковой навигации и Создание Разметка просмотров с вкладками

Кроме того, в этом разделе есть много ответов на stackoverflow.com. Библиотека, которую я предложил, уже упоминалась в этом ответе: fooobar.com/questions/117071/....

Проверьте этот вопрос и соответствующие ответы: Вкладки ниже панели действий

Эти ресурсы должны быть достаточными, чтобы помочь вам с желаемой функциональностью:)

Ответ 3

actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);

actionBar.setLogo(нуль);

    View homeIcon = findViewById(
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
                    android.R.id.home : android.support.v7.appcompat.R.id.home);
    ((View) homeIcon.getParent()).setVisibility(View.GONE);
    ((View) homeIcon).setVisibility(View.GONE);