【问题标题】:How to go back to previous fragment from activity?如何从活动返回到上一个片段?
【发布时间】:2015-07-18 12:20:17
【问题描述】:

我有一个带有导航抽屉的应用程序,它正在切换片段。从其中一个片段中,我正在调用一项新活动。当我在此活动中单击返回(在工具栏中)时,我想返回上一个选定的片段,但它却让我回到第一个片段。我正在将我的片段添加到后台堆栈,所以这应该不是问题。

这是我已经尝试过的:

我已经在我的第二个活动中覆盖了 onBackPressed 方法,如下所示:

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

它不工作。我还在 onsaveinstancestate 方法中保存了当前片段的索引并检索它,但结果相同。我还尝试始终将当前片段放入变量中并尝试重新显示它,但它仍然不起作用。还有什么我可以尝试的吗?

有趣的事实:如果我在底部面板内按回,它实际上会回到上一个片段。

编辑:这是我的代码:

 private void replaceFragment(Fragment fragment)
 {
     if (fragment != null)
     {
         FragmentManager manager = getSupportFragmentManager();
         manager.beginTransaction()
                    .replace(R.id.main_content, fragment)
                    .addToBackStack(null)
                    .commit();
        }
    }

我只添加第一个片段,如果 savedInstanceState 为空,像这样:

if (savedInstanceState == null) {
    // first time
    mTitle = getResources().getString(R.string.home);
    replaceFragment(HomeFragment.newInstance()); 
}

是的,所有这些都是在 onCreate() 方法中完成的。

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    我遇到了同样的问题并得到了解决。你唯一需要做的就是 覆盖activity中的“onOptionsItemSelected”方法:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    

    android.R.id.home 是菜单中的第一个片段。

    【讨论】:

      【解决方案2】:

      我倾向于这样做

      @Override
      public void onBackPressed() {
          if (getFragmentManager().getBackStackEntryCount() == 0) {
              this.finish();
          } else {
              super.onBackPressed(); //replaced
          }
      }
      

      这样它会在内部自行处理片段内容,但是当没有片段可以返回时,它会完成活动。

      编辑:向上导航可以重新创建您以前的活动,即使它已经存在。为防止这种情况发生,请重新定义onOptionsItemSelected 中的Up 导航事件,如下所示:

      public boolean onOptionsItemSelected(MenuItem item) {
          switch (item.getItemId()) {
              case android.R.id.home:
                  Intent parentIntent = NavUtils.getParentActivityIntent(this);
                  if(parentIntent == null) { 
                      finish();
                      return true;
                  } else {
                      parentIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                      startActivity(parentIntent);
                      finish();
                      return true;
                  }
          }
          return super.onOptionsItemSelected(item);
      }
      

      【讨论】:

      • 还是不行。我想我做错了什么。
      • 当我在第二个活动中按回时,它会回到第一个并显示第一个片段,而不是第二个。
      • 您是否也将第一个片段添加到堆栈中,也将第二个片段添加到堆栈中?您使用的是add 还是replace?仅当保存实例状态为空时才添加片段?你在 onCreate 做这个吗?贴出第一个活动相关方法的代码。
      • Ohhhhhhhhh..... 等一下,您正尝试使用向上导航返回。等等,我有一个解决办法:stackoverflow.com/a/30059708/2413303
      • 就是这样!谢谢!
      【解决方案3】:

      当您从其他活动的片段中调用活动时,前一个活动的实例状态(即具有片段实例状态的调用活动)将保存在堆栈中......所以您需要做的就是完成被调用的活动并您将拥有您从中调用第二个活动的片段。

      @Override
      public void onBackPressed() {
      finish();
      }
      

      【讨论】:

        【解决方案4】:

        试试

        getFragmentManager().popBackStackImmediate();
        

        它对我有用。

        【讨论】:

          【解决方案5】:

          抱歉,我没有足够的声誉来发表评论。所以我不得不猜测。我曾经有同样的问题。 听起来像是与活动生命周期有关的问题 (http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle)。请务必只添加一次您的第一个片段,因为您的活动的片段管理器具有生命周期的能力。 因此,将第一个片段添加到片段管理器的语句应该被 if (savedInstanceState == null) { ... } 包围。

          【讨论】:

          • 我已经处理好了:if (savedInstanceState == null) { mTitle = getResources().getString(R.string.home); replaceFragment(HomeFragment.newInstance());
          【解决方案6】:

          我明白了,人们仍在努力帮助我。这个答案帮助我解决了我的问题:Android - Navigation Up from Activity to Fragment

          【讨论】:

            【解决方案7】:

            在activity中重写onOptionsItemSelected方法如下,

            @Override
            public boolean onOptionsItemSelected(MenuItem item) {
                int id = item.getItemId();
                if (id == android.R.id.home) {
                    finish();
                }
                return super.onOptionsItemSelected(item);
            }
            

            【讨论】:

              【解决方案8】:

              当你从 Fragment 调用新的 Activity 时,你应该写:

              Intent intent = new Intent(getFragment().getContext(),NewActivity.class);
              getFragment().getContext().startActivity(intent);
              
              FragmentManager fm = CurrentFragment.getActivity().getSupportFragmentManager();
              FragmentTransaction ft = fm.beginTransaction();
              ft.addToBackStack(CurrentFragment.class.getName()).commit();
              fm.executePendingTransactions();
              

              它对我有用。

              【讨论】:

                【解决方案9】:
                getSupportFragmentManager().beginTransaction()
                                           .setReorderingAllowed(true)
                                           .addToBackStack("home") // should not be null
                                           .replace(binding.fragmentContainer.getId(), new HomeFragment())
                                           .commit();
                

                addToBackStack(String name) 方法中传递名称。如果传递的名称不为空,此函数将片段添加到后台堆栈。 App自动开始管理fragment的backstack

                删除您的覆盖 onBackPressed() 方法。现在不用了

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-05-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-08-30
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多