当前位置: 首页 > 知识库问答 >
问题:

Android ViewPageAdapter,每个标签都有一个单独的背栈

柳涵映
2023-03-14

我有一个单一活动的Android应用程序。该活动包含一个带有ViewPageAdapter的SlidingTabLayout,如本例所示。每个选项卡都包含一个相应的根片段,当用户使用该屏幕时,我将其替换为其他片段。一个可视化表示如下所示:

在当前的实现中,我执行以下操作:转到tab1,用ProductListFragment替换ProductRootFragment立即加载ProductListFragment。我单击一个产品,它将ProductListFragment替换为ProductDetailment。现在我切换到tab2,并且通过替换tab2rootfragment立即加载Tab2ListFragment。我单击一个项目,然后Tab2DetailFragment替换了tab2listfragment。现在返回到Tab1,正如我所料,ProductDetailFragment仍然显示。但是,如果我现在单击back按钮,它不会像我预期的那样将我带回ProductListFragment。相反,它从背堆栈中弹出Tab2DetailFragment。

我想为每个“tab”片段实现一个单独的backstack。已经有几个关于这一点的帖子,但它们似乎都过时了,有些提出了非常详细的解决方案。(看这里,这里,这里……)

@Override
public Fragment getItem(int position) {
    switch(position){
        case 0: return new ProductRootFragment();
        ...
    }
    ...
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.product_root_fragment, container, false);

    FragmentTransaction transaction = getFragmentManager()
            .beginTransaction();
    transaction.replace(R.id.product_root_container, new ProductListFragment());
    transaction.commit();
    return view;
}

ProductListFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View layout = inflater.inflate(R.layout.product_list_fragment, container, false);
    view = (ProductListView) layout;
    return view;
}
...
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    ...
    ProductDetailFragment newFragment = new ProductDetailFragment();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.product_root_container, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

ProductDetailFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = (ProductDetailView) inflater.inflate(R.layout.product_detail_fragment, container, false);
    return view;
}

共有1个答案

淳于飞鸾
2023-03-14

我知道现在回答这个问题已经很晚了,但也许有人还需要它。为此,必须在根片段中使用getChildFragmentManager()而不是getFragmentManager()

例如,我有一个带有ViewPager和TabLayout的活动,我将rootfragment1rootfragment2添加到ViewPager,并使用ViewPager设置TabLayout。现在,在我的rootfragment1替换我的tab1fragment1中,我使用以下代码:

final FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.replace(R.id.RootFrame1, Tab1Fragment1.newInstance(), "MyTag");
ft.commit();

并且需要从backstack弹出片段的方法如下:

public boolean popBackStack() {
    if(getChildFragmentManager().getBackStackEntryCount() > 0) {
        getChildFragmentManager().popBackStackImmediate();
        return true;
    } else
        return false;
}
button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        final FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.RootFrame1, Tab1Fragment2.newInstance(), "MyTag");
        ft.addToBackStack(null);
        ft.commit();
    }
});
@Override
public void onBackPressed() {
    if (viewPager.getCurrentItem() == 0) {
        RootFragment1 fragment = ((RootFragment1) sectionsPagerAdapter.getItem(0));
        if (!fragment.popBackStack())
            super.onBackPressed();
    } else if (viewPager.getCurrentItem() == 1) {
        RootFragment2 fragment = ((RootFragment2) sectionsPagerAdapter.getItem(1));
        if (!fragment.popBackStack())
            super.onBackPressed();
    } else
        super.onBackPressed();
}
 类似资料:
  • 我正在为一个看起来像这样的纸牌游戏制作一个反应大厅:大厅图像 每个名称和“kick”按钮都是一个react组件,我根据名称列表(该列表中的所有名称都是唯一的)呈现该组件。我认为,由于名称是唯一的,我可以使用名称作为键,但由于某些原因,我得到以下错误:错误消息 我做错了什么? 注意:我还尝试了为KickButton键做key={Player"1"},以使其与相应的PlayerIcon唯一,但错误仍然

  • 我在活动中有四个底部选项卡,其中一个选项卡将导航到另一个活动。这个活动有2个片段,四个选项卡中的每一个控制一个片段,当我点击(活动有2个片段)的选项卡时,应用程序停止 如有任何帮助,请提前感谢

  • 我正在为某个游戏开发某种“分数跟踪器”应用程序。用户添加一定数量的玩家(当前数量是无限的),然后这些玩家的名字被添加到ArrayList中。然后在下一个活动中,用户必须从一个旋转器中选择一个playername,并为该玩家输入一定数量的“点数”,或者说“分数”。 这是我当前的代码: 现在我要做的是实现一个功能,它将跟踪每个球员的得分。 示例:用户添加了2个玩家,一个叫约翰,一个叫杰克。然后用户给约

  • 我正在尝试使用ChartJS图表加载图表后单击每个标签。我编写了以下代码,但无法通过我所拥有的内容。任何见解或帮助都将不胜感激。 我正在尝试绘制图表,以便在首次加载时,每个标签都被划掉并隐藏。我有正确的想法将其设置为隐藏和更新吗?谢谢!

  • 问题内容: 我想写一些类似的东西: 这有效: 这有效: 像这样的作品: 但是我需要在Meeting_time上做一个大于查询的事情,所以我需要将它写为一个字符串,我认为呢? 但是,两个sql查询在一起都会产生以下错误: 我觉得我好近……我在这里想念什么? 问题答案: 当不清楚该列来自哪个表时,会出现此消息。这应该工作: