Actionbar Sherlock - 在横向划动时标签页不会改变

7

我有一个使用ViewPager + ActionBar Sherlock标签的屏幕。我在pager上设置了setOnPageChangeListener,它会执行以下操作:

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

这在纵向模式下运作良好,即使在横向模式下也是如此,只要我只有几个选项卡且所有选项卡都被显示。但是,如果我在横向模式下添加了更多选项卡,它们将折叠成单个下拉组件。当我通过ViewPager翻页时,会执行setSelectedNavigationItem方法,但现在它对下拉列表选择没有影响:它保留在最后一个选定的值。这真的很糟糕,因为用户缺少视觉提示:选项卡可能会显示“一”,但用户已经在第6页。

是否有一种基于位置编程地更改要显示的选项卡的方法?

P.S. 我知道为什么会发生这种情况: 这是来自com.android.internal.app.ActionBarImpl的代码:

public void setSelectedNavigationItem(int position) {
    switch (mActionView.getNavigationMode()) {
    case NAVIGATION_MODE_TABS:
        selectTab(mTabs.get(position));
        break;
    case NAVIGATION_MODE_LIST:
        mActionView.setDropdownSelectedPosition(position);
        break;
    default:
        throw new IllegalStateException(
                "setSelectedNavigationIndex not valid for current navigation mode");
    }
}

当我浏览代码时,我发现导航模式仍然是NAVIGATION_MODE_TABS,尽管选项卡已显示为列表。我的第一反应是在onConfigurationChanged中加入代码以适当设置导航模式,但这是否应该自动完成呢?

P.S. 已经有一个Android bug有人提出,并包含了补丁。

2个回答

11

基于我在问题中提到的Android bug(见P.P.S.),以下是一个确实有效的解决方法。只需将其添加到您的页面即可。

mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
     {
        @Override
        public void onPageSelected(int position)
        {
           actionBar.getTabAt(position).select();
           ViewParent root = findViewById(android.R.id.content).getParent();
           findAndUpdateSpinner(root, position);
        }

        /**
         * Searches the view hierarchy excluding the content view 
         * for a possible Spinner in the ActionBar. 
         * 
         * @param root The parent of the content view
         * @param position The position that should be selected
         * @return if the spinner was found and adjusted
         */
        private boolean findAndUpdateSpinner(Object root, int position)
        {
           if (root instanceof android.widget.Spinner)
           {
              // Found the Spinner
              Spinner spinner = (Spinner) root;
              spinner.setSelection(position);
              return true;
           }
           else if (root instanceof ViewGroup)
           {
              ViewGroup group = (ViewGroup) root;
              if (group.getId() != android.R.id.content)
              {
                 // Found a container that isn't the container holding our screen layout
                 for (int i = 0; i < group.getChildCount(); i++)
                 {
                    if (findAndUpdateSpinner(group.getChildAt(i), position))
                    {
                       // Found and done searching the View tree
                       return true;
                    }
                 }
              }
           }
           // Nothing found
           return false;
        }
     });

这个解决方案适用于原生的ActionBar,但不适用于兼容性ActionBar(在Gingerbread模拟器上)。如何修复这个问题? - Gal Ben-Haim

0

你需要在 ActionBarSherlock 库项目的文件 (ActionBarImpl.java) 中添加一些代码,请参见 this link


你指出的修复方法不起作用,我刚刚检查过了。这段代码仅在onConfigurationChanged中调用,但是我需要在从一页滑动到另一页时更改所选选项卡。 - Bostone
如果您正在使用ViewPager,则需要在其监听器中显式设置所选选项卡...这是我在一个项目中所做的。 - Amit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接