【问题标题】:Popbackstack Finishes Activity in OnBackPressedPopbackstack 在 OnBackPressed 中完成 Activity
【发布时间】:2015-05-14 06:49:16
【问题描述】:

我有一个包含两个片段(列表和详细信息)的活动,在 onCreate() 中,如果 savedInstance 为空,我会启动列表片段

 public static final int CLIENT_LIST_FRAGMENT = 1;
 public static final int CLIENT_DETAILS_FRAGMENT = 2;
 private int currentFragment = 0;

if (savedInstanceState == null) {
            //On first run, start the list fragment
            if (currentFragment == 0) {
                ClientListFragment listFrag = new ClientListFragment();
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.container_client, listFrag, Constants.CLIENT_LIST_FRAGMENT_TAG)
                        .commit();
                currentFragment = CLIENT_LIST_FRAGMENT;
            } else {
                switch (currentFragment) {
                    case CLIENT_LIST_FRAGMENT:
                        addListFragment();
                        break;
                    case CLIENT_DETAILS_FRAGMENT:
                        addDetailsFragment(0);
                        break;
                }
            }
        }

这里是根据需要添加 DetailsFragment 和 ListFragment 的方法

 private void addListFragment(){
        ClientDetailsFragment listFrag = new ClientDetailsFragment();
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container_client, listFrag, Constants.CLIENT_LIST_FRAGMENT_TAG)
                .addToBackStack("details")
                .commit();
        currentFragment = CLIENT_LIST_FRAGMENT;
    }

    private void addDetailsFragment(long companyId){
        ClientDetailsFragment detailsFrag = ClientDetailsFragment.newInstance(companyId);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container_client, detailsFrag, Constants.CLIENT_DETAILS_TAG)
                .addToBackStack(null)
                .commit();
        currentFragment = CLIENT_DETAILS_FRAGMENT;

    }

这按预期工作,只是当我从详细信息片段中单击后退按钮时,它并没有将我带回列表片段,而是实际上完成了活动。它会在一瞬间返回到 List Fragment,然后完成主机 Activity 并返回到调用 Activity。在经历了很多关于 SO 的 onBackpress 相关问题后,我该如何阻止这种行为,这是我对 onBackPressed 的替代

@Override
    public void onBackPressed() {
        if (currentFragment == CLIENT_DETAILS_FRAGMENT){
            getSupportFragmentManager().popBackStackImmediate();
        }else {
            super.onBackPressed();
        }
    }

谢谢

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    Activity onBackPressed() 应该是:

    对于 android.support.v4.app.Fragment

    @Override
    public void onBackPressed() {
        if (getSupportFragmentManager().getBackStackEntryCount() > 1)
            getSupportFragmentManager().popBackStack();
        else
            finish();
    }
    

    对于 android.app.Fragment

    @Override
    public void onBackPressed() {
        if (getFragmentManager().getBackStackEntryCount() > 1)
            getFragmentManager().popBackStack();
        else
            finish();
    }
    

    【讨论】:

      【解决方案2】:

      我通常检查当前片段实例是否属于调用onBackPressed()的片段。此代码未经测试;这只是为了让您了解如何进行。我希望你不要在 Activity 上调用 this.finish()

      @Override
      public void onBackPressed() {
          Fragment fragment = getSuportFragmentManager().findFragmentByTag(Constants.CLIENT_DETAILS_TAG);
          if (fragment instanceof ClientDetailsFragment) {
              getSupportFragmentManager().popBackStackImmediate();
          }
          else {
              super.onBackPressed();
          }
      }
      

      如果有帮助,请告诉我。

      【讨论】:

      • 谢谢,我会尝试一下你的代码,我已经解决了 onDestroy 被调用的事实,无论我如何处理 onbackpressed 所以我现在的挑战是弄清楚如何阻止 onDestroy 被调用当我调用 onBackpressed 时
      • 嗯,这意味着 this.finish() 正在被 applicationsystem 调用(该 Activity 实例正在被销毁为了节省空间) Check documentation.
      • 嗯,在一个简单的应用程序上。谢谢,我想看看如何防止这种情况。感谢您的代码,它为我指明了正确的方向。
      【解决方案3】:

      上帝啊,我这两天追错了影子。我在听、处理和覆盖错误的事件。

      这个 SO 问题救了我Why is onBackPressed() not being called?

      要点是 "onBackPressed() 在用户单击硬件后退按钮(或导航栏中的“向上”按钮)时调用,而不是操作栏中的按钮。对于这个你需要重写 onOptionsItemSelected() 方法。示例:"

      我在片段中捕捉到这个事件并调用 getActivity.onBackpressed。当我停止这个时,对我来说很明显 onBackPressed 没有被调用。这是我的解决方案,可能不是最佳的,但它有效

      if (item.getItemId() == android.R.id.home){
                  if (currentFragment == CLIENT_DETAILS_FRAGMENT){
                      getSupportFragmentManager().popBackStackImmediate();
                      currentFragment  = CLIENT_LIST_FRAGMENT;
                      return true;
                  }
              }
      

      【讨论】:

        【解决方案4】:
         if (currentFragment == 0) {
                    ClientListFragment listFrag = new ClientListFragment();
                    getSupportFragmentManager().beginTransaction()
                            .add(R.id.container_client, listFrag, Constants.CLIENT_LIST_FRAGMENT_TAG)
                            .commit();
                    currentFragment = CLIENT_LIST_FRAGMENT;
                }
        

        同时将此添加更改为 addToBackStack()

        并且, 改变 onBackPressed() 之类的,

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

        希望,这会奏效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-07
          相关资源
          最近更新 更多