Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 切换制表符时重置碎片回撤_Android_Android Fragments_Tabs - Fatal编程技术网

Android 切换制表符时重置碎片回撤

Android 切换制表符时重置碎片回撤,android,android-fragments,tabs,Android,Android Fragments,Tabs,在互联网上找不到答案后,我开始问我的第一个问题。通常这应该是一件非常简单的事情,但它花了我好几个小时,所以请原谅,如果这是一个初学者的问题。另外,我想确保在花更多的时间之前我走的是正确的道路,只是为了看到最终它并没有像我想要的那样工作,我实现它的方式 问题: 我的应用程序有3个选项卡,其中3个片段作为内容,每个选项卡一个。我使用标签是因为我要求的所有用户都需要标签,而不是导航抽屉。我听用户的,而不是谷歌的(对不起)。此外,这3个选项卡具有非常不同的“角色”(语言指南、货币兑换器和自己的短语笔记本

在互联网上找不到答案后,我开始问我的第一个问题。通常这应该是一件非常简单的事情,但它花了我好几个小时,所以请原谅,如果这是一个初学者的问题。另外,我想确保在花更多的时间之前我走的是正确的道路,只是为了看到最终它并没有像我想要的那样工作,我实现它的方式

问题:

我的应用程序有3个选项卡,其中3个片段作为内容,每个选项卡一个。我使用标签是因为我要求的所有用户都需要标签,而不是导航抽屉。我听用户的,而不是谷歌的(对不起)。此外,这3个选项卡具有非常不同的“角色”(语言指南、货币兑换器和自己的短语笔记本等),这样划分是有意义的(imo)。如果有人有其他想法,请继续,我是开放的:-)

到目前为止,选项卡导航按预期工作。但是现在我想为单个标签建立进一步的导航,我不确定该怎么走。。。像这样一件简单的事情有很多方法

第一个选项卡有一些图像按钮,可以进一步导航到此部分(请参见屏幕截图1),在语言部分中选择一个类别。当然,这意味着选项卡应该保持在原位,以便能够轻松切换到转换器,也就是说,只需将选项卡1中的片段切换到新片段(参见屏幕截图2),依此类推。您在下面的屏幕截图中看到的按钮具有clicklisteners,可以将当前片段更改为新片段(如“Daily”)

为此,我打开另一个片段并将其添加到backbackback。也许你已经猜到现在发生了什么。如果我按下后退按钮,我当然会回到第一个片段。当我在选项卡1上打开的片段中切换选项卡时,问题就开始了。添加的片段仍然在backback中,这意味着如果我按下选项卡2或3上的back按钮,显示的内容会与其他片段的内容混淆。见截图3

我是否在此处出错,或者在切换选项卡时,我是否可以简单地告诉Backback“重置”,以避免出现此问题

谢谢你提供的信息,并为语言和拼写错误感到抱歉,英语不是我的主要语言

切换选项卡片段的TablListener类:

public  class MyTabListener implements ActionBar.TabListener {
Fragment fragment;

public MyTabListener(Fragment fragment) {
    this.fragment = fragment;
}

public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
    ft.replace(R.id.fragment_container, fragment);
}

public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
    ft.remove(fragment);
}

public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
    // nothing done here
}
}

第一个片段中的Fragments类如下所示(不是完整代码):

主要活动:

public class MainActivity extends Activity {
ActionBar.Tab tab1, tab2, tab3;
Fragment fragmentTab1 = new FragmentTab1();
Fragment fragmentTab2 = new FragmentTab2();
Fragment fragmentTab3 = new FragmentTab3();

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_tab_test);

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    tab1 = actionBar.newTab().setText("Home");
    tab2 = actionBar.newTab().setText("Calculator");
    tab3 = actionBar.newTab().setText("Notebook");

    tab1.setTabListener(new MyTabListener(fragmentTab1));
    tab2.setTabListener(new MyTabListener(fragmentTab2));
    tab3.setTabListener(new MyTabListener(fragmentTab3));

    actionBar.addTab(tab1);
    actionBar.addTab(tab2);
    actionBar.addTab(tab3);
无法发布图片,代表过低

请看这里(第三张图片名为Untitled-3.png)

屏幕1:

屏幕2:


屏幕3:

您最好不要使用片段后堆栈。您可以维护自己的堆栈并重写
onBackPressed()
,以提供适当的行为

@Override protected void onBackPressed()
{
    if(myStack.isEmpty())
        super.onBackPressed(); // default handling finishes the activity
    else
    {
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, myStack.pop());
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
        transaction.commit();            
    }
}
您可以尝试以下操作:

public void onTabSelected(YourTab tab) {
    Fragment fragment = new YourTabFragment();
    replaceRootFragment(fragment);
}

public void replaceRootFragment(Fragment fragment) {
    if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
        int id = getSupportFragmentManager().getBackStackEntryAt(0).getId();
        try {
            getSupportFragmentManager().popBackStackImmediate(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        } catch (IllegalStateException e) {
            return;
        }
    }
    getSupportFragmentManager().beginTransaction()
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
            .replace(R.id.container, fragment)
            .commit();
}

当你点击标签时,点击Tab选中。

实际上,听起来你可能想考虑一个完全不同的方法。如果我的理解正确,你可能想考虑使用一个带有FractPrar适配器的VIEWPPAGE(参见谷歌文档代码示例:) 实际上,viewpager在选项卡下显示片段,适配器提供要显示的片段列表,您可以通过调用viewpager上的setCurrentItem(当用户单击选项卡时)选择当前“页面”。此外,用户还可以在页面之间滑动(您可以通过收听寻呼机事件更新所选选项卡,请参见此处的google文档代码示例:)

这种方法避免了整个backbackback问题,听起来更像是您所追求的


希望有帮助。

嗯,谢谢,这是需要考虑的,是的。但是,当按下另一个选项卡或当前选项卡失去焦点时,是否也有简单地重新初始化原始状态的功能?我在API指南中找不到这个。如果不是,我很乐意试试你的建议。导航不会像2那样首先进入“堆栈”,我的意思是从语言指南片段它进入一个类别,然后会有一个列表视图打开条目的细节。我的经验是,内置行为并不像我们希望的那样灵活。我经常以这样的方式处理它,用我自己的堆栈。再次感谢,我明天会尝试,然后回到这里接受答案或继续前进^^我会尝试!现在谢谢。嗯,你打算在哪里实施这个?在onTabSelected、onTabSelected或my button onclick函数中打开新片段?好的,现在看起来更有希望了。在我尝试这个时遇到了很多问题之前。我稍后会尝试更新,谢谢。不确定为什么我既没有访问getSupportFragmentManager的权限,也没有访问getFragmentManager的权限,甚至Fragmentmanager已导入。我仍然得到cannotrelovethod getFragmentManager(),它隐藏在哪里?我没有通过Alt*enter获得任何导入。忘记我的最后一条评论:-)在错误的类中。无法获取该方法,因为它扩展了活动而不是片段。它真的让我抓狂。。。为什么即使是在谷歌开发页面上,对于一个问题也必须有5种不同的方式,那么为什么在API指南中显示的所有代码中,没有一种与从(谷歌)模板构建新项目时得到的代码相匹配。是的,事实上,这就是我以前一直在寻找的,我现在这样做。这是迄今为止更好的方法。遗憾的是,我没有看到这个代码示例,而是使用了提供的带有选项卡的模板&Swipepager,基本上是一样的。。。。但是模板代码远远超出了我的理解,我甚至不知道当我想用这个例子添加我自己的片段时,从哪里开始。为什么它必须过于复杂,我想要的只是一个标准的导航?但我现在就从你那里试试这个例子,它似乎更容易理解。谢谢。不幸的是,这就是所谓的“双刃剑”,Android平台给了你很大的自由,可以用不同的方式表达问题的解决方案。。但是通常很难找到最好的方法。。甚至“最佳实践”也经常被忽略
public void onTabSelected(YourTab tab) {
    Fragment fragment = new YourTabFragment();
    replaceRootFragment(fragment);
}

public void replaceRootFragment(Fragment fragment) {
    if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
        int id = getSupportFragmentManager().getBackStackEntryAt(0).getId();
        try {
            getSupportFragmentManager().popBackStackImmediate(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        } catch (IllegalStateException e) {
            return;
        }
    }
    getSupportFragmentManager().beginTransaction()
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
            .replace(R.id.container, fragment)
            .commit();
}