当前位置: 首页 > 面试题库 >

ActionBar选项卡内容重叠

司空修贤
2023-03-14
问题内容

我在StackOverflow中发现了大量这些消息。像其他许多人一样,切换标签时,标签内容重叠也存在相同的问题。我发现的任何建议都无法解决我的问题。

当我的应用启动时,它会正确显示第一个选项卡的内容。当我单击另一个选项卡时,旧内容保留在屏幕上,另一个选项卡的内容也添加在屏幕上。第二次切换选项卡时,所有内容均消失。切换标签不再有用。

我在这里关注了Google的Developer文档。

我的应用程序具有此onCreate方法。该类ActionBarActivity从支持libary
扩展android.support.v7.app

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

    ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(false);

    Tab tab = actionBar.newTab().setText("TAB1").setTabListener(new TabListener<Tab1Class>(this, "tab1", Tab1Class.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab().setText("TAB2").setTabListener(new TabListener<Tab2Class>(this, "tab2", Tab2Class.class));
    actionBar.addTab(tab);
}

我的TabListener课程是从我链接的页面复制的:

public class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if(mFragment == null) {
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            ft.attach(mFragment);
        }
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if(mFragment != null) {
            ft.detach(mFragment);
        }
    }

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

我使用的两个类都是选项卡的内容,它们从扩展了Fragment
android.support.v4.app.Fragment。他们在onCreateView方法中增加其布局。

怎么了?


问题答案:

怎么了?

快速浏览完的代码后ActionBarActivity,似乎实现了ICS及以上部分的错误ActionBar(该代码应适用于前置ICS设备),该错误也需要注意这些选项卡。

ActionBarImplICS代表ICS设备实现的类中,FragmentTransaction传递给onTabUnselected()回调的方法似乎完全没有用,因为它没有在侦听器的回调返回之后的任何地方提交(事务针对的其他两个回调而提交TabListener)。因此,提交的片段将永远不会与选项卡上的布局分离,并且它将保持获取重叠的内容(由于FrameLayout包含两个片段)。

我编写了该TabListener接口的另一种实现,该接口的全部工作仅由不受上述bug(onTabSelected())影响的一个回调完成:

public class TabListenerImpl implements ActionBar.TabListener {

    private List<TabInfo> mTabs = new ArrayList<TabInfo>();
    private Context mContext;

    public TabListenerImpl(Context context) {
        mContext = context;
    }

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

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // iterate over all of the tabs, match the tag we have and see if
        // we also have a fragment instance for it. If we don't, create one
        // and add it to the container, if we have an instance simply attach
        // it. Detach every other tag which doesn't match the tag.
        for (TabInfo t : mTabs) {
            if (tab.getTag() == t.tag) {
                if (t.pageFragment == null) {
                    t.pageFragment = Fragment.instantiate(mContext,
                            t.clazz.getName());
                    ft.add(android.R.id.content, t.pageFragment, t.tag);
                } else {
                    ft.attach(t.pageFragment);
                }
            } else {
                if (t.pageFragment != null && !t.pageFragment.isDetached()) {
                    ft.detach(t.pageFragment);
                }
            }
        }
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // faulty method
    }

    /**
     * Call this method BEFORE you call the actionBar.addTab() method!
     * 
     * @param tag
     *            a String representing the tag that was set on the tab to
     *            identify itself
     * @param clazz
     *            the class of the Fragment
     */
    public void addTab(String tag, Class<? extends Fragment> clazz) {
        TabInfo ti = new TabInfo();
        ti.clazz = clazz;
        ti.tag = tag;
        mTabs.add(ti);
    }

    // wrapper class
    private class TabInfo {
        Class<? extends Fragment> clazz;
        Fragment pageFragment;
        String tag;
    }

}

然后可以将其用作:

TabListenerImpl listener = new TabListenerImpl(this);
Tab tab = actionBar.newTab().setText("TAB1").setTag("TAB1").setTabListener(listener);
listener.addTab("TAB1", Tab1Class.class);
actionBar.addTab(tab);

tab = actionBar.newTab().setText("TAB2").setTag("TAB2").setTabListener(listener);
listener.addTab("TAB2", Tab2Class.class);
actionBar.addTab(tab);

我建议您将容器设置为内容视图(以及标签内容),而不要使用该android.R.id.content容器。请记住,我的实现没有考虑配置更改。



 类似资料:
  • 我正在开发一个应用程序,使用ActionBar导航,我有3个标签(我不使用tabhost)如下图: 在第一个选项卡中,将显示一个名为FragmentListItem的片段,如果单击Item1,FragmentListItem将被另一个名为FragmentItemDetails的片段替换,该片段显示所选项的详细信息。 我的问题是,当我选择Tab2或tab3,然后再次选择Tab1,我得到的不再是fra

  • 我对tabView有问题。第一个选项卡应始终显示相同的内容(称为搜索模板,用#{not curSearch.isClosable()}标识)。所有其他选项卡都是搜索实例(用#{curSearch.isClosable()}标识) 代码如下: 不幸的是,在第一个选项卡上有一些被称为curSearch对象的方法,这些方法仅在第二个选项卡和后面的选项卡上使用。如果我不使用ui:insert,它不会改变任

  • 我很好奇,让内容(例如div)在t:panelTabbedPane中占据100%的t:panelTab的正确方式是什么。内容似乎是在无法指定样式的div或span中呈现的。我能做到这一点的唯一方法就是使用绝对布局。有更好的办法吗?

  • 问题内容: 我有一个常规的Twitter Bootstrap 3标签。我要做的就是控制 一个元素来控制多个容器。 在此示例中,当我更改标签时,仅第一个被更改。我要两个容器都改变,而不仅仅是第一个。 谢谢! 问题答案: 我将 data-target 属性添加到a元素并更改第二个tab内容中的id 我修改了这行 您的: 我的更新: 第二个选项卡内容,您的: 我的更新:

  • 问题内容: 我有包含大量数据的大型表格,所以我希望每个标签都带有大量数据的标签。 我希望在单击标签标题时可以延迟加载标签内容,然后在以后再次选择时不需要再次重新加载。 我认为这个示例符合我想要的方向: [ngular-ui选项卡在tab-content中加载模板 但这似乎加载了一个静态模板: 如何使用$ http.get()动态加载窗格的内容?注意:这已经是通过ng-view路由加载的页面,因此我