Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.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_Fragment_Back - Fatal编程技术网

Android 如何在手动按下单个片段的后退按钮时返回到上一个片段?

Android 如何在手动按下单个片段的后退按钮时返回到上一个片段?,android,fragment,back,Android,Fragment,Back,我的应用程序中只有一个活动和多个片段 两个主要片段A(左)和B(右)。 Fragment A1 called from A B1 called from B B2 called from B1 所有片段都有单独的后退按钮 因此,当我按下fragmentA1的后退按钮时,它应该返回到A,类似地,当按下B2的后退按钮时,B1出现,从B1到B等等 如何实现这种类型的功能?后退按钮将按片段的顺序遍历。默认情况下,这是作为导航功能提供的。现在,如果您想转到特定的片段,您可以从backstack开始。

我的应用程序中只有一个
活动
和多个
片段

两个主要片段A(左)和B(右)。

Fragment A1 called from A

B1 called from B

B2 called from B1
所有
片段都有单独的后退按钮

因此,当我按下
fragment
A1的后退按钮时,它应该返回到A,类似地,当按下B2的后退按钮时,B1出现,从B1B等等


如何实现这种类型的功能?

后退按钮将按片段的顺序遍历。默认情况下,这是作为导航功能提供的。现在,如果您想转到特定的片段,您可以从backstack开始。

您必须实现您自己的backstack实现,如前所述


无论何时单击片段中的后退按钮,都可以调用
popFragments()
,无论何时从一个片段导航到另一个片段,都可以调用
pushFragments()

您可以通过在
backStack
中添加标记来处理它。在这里检查我的答案:

public void onBackPressed()
{
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();
}

希望能有帮助

@Override
public void onResume() {

    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                // replace your fragment here

                return true;

            }

            return false;
        }
    });
}

//快乐编码

我刚刚实现了类似的场景

活动“A”->调用片段“A1”,单击菜单项,它调用片段“A2”,如果用户从“A2”按下后退按钮,这将返回到“A1”,如果用户在这之后从“A1”按下后退按钮,它将完成活动“A”并返回

请参阅以下代码:

活动“A”-OnCreate()方法:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activityA);

    if (savedInstanceState == null) {
        Fragment fragInstance;

        //Calling the Fragment newInstance Static method
        fragInstance = FragmentA1.newInstance();

        getFragmentManager().beginTransaction()
                .add(R.id.container, fragInstance)
                .commit();
    }
}

片段:“A1”

当菜单项click action发生时,我正在用新片段替换现有片段:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_edit_columns) {
        //Open the Fragment A2 and add this to backstack
        Fragment fragment = FragmentA2.newInstance();
        this.getFragmentManager().beginTransaction()
                .replace(R.id.container, fragment)
                .addToBackStack(null)
                .commit();

        return true;
    }
    return super.onOptionsItemSelected(item);
}

活动“A”-onBackPressed()方法:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activityA);

    if (savedInstanceState == null) {
        Fragment fragInstance;

        //Calling the Fragment newInstance Static method
        fragInstance = FragmentA1.newInstance();

        getFragmentManager().beginTransaction()
                .add(R.id.container, fragInstance)
                .commit();
    }
}
由于所有片段都有一个父活动(即“A”),因此onBackPressed()方法允许您弹出片段(如果有),或者只返回到上一个活动

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else {
        getFragmentManager().popBackStack();
    }
}

如果您想在片段中嵌入片段,请参考链接:

试试这个,它适合我

public void onBackPressed() {
    if (mainLayout.isMenuShown()) {
        mainLayout.toggleMenu();
    } else {
        FragmentManager fm = getSupportFragmentManager();
        Log.print("back stack entry", fm.getBackStackEntryCount() + "");

        if (fm.getBackStackEntryCount() > 1) {
            fm.popBackStack();
            // super.onBackPressed();
            // return;
        } else {
            if (doubleBackToExitPressedOnce) {
                fm.popBackStack();
                super.onBackPressed();
                return;
            }

            this.doubleBackToExitPressedOnce = true;
            Toast.makeText(this, "Press one more time to exit",
                    Toast.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {

                    doubleBackToExitPressedOnce = false;
                }
            }, 3000);

        }
    }
}
照办

getActivity().getFragmentManager().popBackStack();

@trueblue的回答让我想到了一个小问题,但很烦人。当Backback上只有一个片段,并且您按下back按钮时,该帧将被删除,应用程序将在空白屏幕上保持活动状态。用户需要再按一次后退按钮才能退出应用程序。为了处理这种情况,我将原始代码修改为如下内容

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        getFragmentManager().popBackStack();
    }
}
当Backback中只有一个片段时,我们基本上是告诉android将整个应用程序向后移动

更新(可能是更好的答案) 所以在阅读了更多关于这方面的文章后,我发现你可以,然后安卓会自动地以一种想要的方式处理回压。下面的代码片段展示了如何做到这一点

Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);
最后一行显示如何将事务添加到后台堆栈。这解决了大多数情况下(只有一种情况除外)碎片的回压问题。如果您继续按后退按钮,那么最终您将到达一个点,即在后堆栈中只有一个片段。在这一点上,您将要做以下两件事之一

  • 从运行活动的任务的后堆栈中删除包含该片段的活动。这是因为您不希望以空白活动结束
  • 如果该活动是任务后堆栈中的唯一活动,则在后台推送该任务
  • 在我的例子中,它是后者,所以我修改了前面答案中重写的
    onBackPressed
    方法,如下所示

    @Override
    public void onBackPressed() {
        if(getFragmentManager().getBackStackEntryCount() == 1) {
            moveTaskToBack(false);
        }
        else {
            super.onBackPressed();
        }
    }
    

    这段代码更简单,因为它的逻辑更少,而且它依赖于框架,而不是我们的自定义代码。不幸的是,我没有为第一种情况实现代码,因为我不需要这样做。

    如果您按下back image,您必须像这样首先创建方法

    private void Backpresses() {
        getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.contant_main, new Home()).commit();
    }
    
    然后,当你按下“后退图像”时,你必须这样打电话

     back.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                       Backpresses();
    
                    }
                });
    

    它对我来说很好。

    所有片段都有单独的后退按钮。
    这对我来说毫无意义。请您进一步解释一下好吗?左片段A和右片段B,我在A中有3个按钮。按下A的第一个按钮时,会显示A1。我有A1中的listview。单击listview项时,其详细信息显示在右侧片段B1上。A的其他2个按钮也是如此。如果使用import android.support.v4.app.FragmentManager,则为最佳答案;我认为这是最好的答案,因为你真的不想忘记先“addToBackStack”你的片段。否则,后面就没什么可爆的了!是的..没有人提到
    addToBackStack
    方法。谢天谢地,我也在做类似的流程,这对我处理背压有很大帮助。这需要更多的选票!这对我很有用。谢谢我得到了java.lang.IllegalStateException:当我在commit()之后调用addToBackStack(null)时,在commit()之后调用了addToBackStack();在修复问题之前移动它