【问题标题】:How to close the current fragment by using Button like the back button?如何使用像后退按钮这样的按钮来关闭当前片段?
【发布时间】:2014-01-15 18:25:10
【问题描述】:

我尝试使用 Imagebutton 关闭当前片段。

我在Fragment-A,点击按钮会转到Fragment-B。

当我点击 Fragment-B 的按钮时,它会转到 Fragment-C 并关闭 Fragment-B。

如果我点击 Fragment-C 的返回按钮,它将返回 Fragment-A。

我尝试过的代码如下

camera_album = (ImageButton) view.findViewById(R.id.camera_album);

camera_album.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View v) {

                    closefragment();
        Fragment fragment = FileBrowserFragment.newInstance(null, null, null) ;
        MainActivity.addFragment(LocalFileBrowserFragment.this, fragment) ;


    }
});

private void closefragment() {
    getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}

当我单击 fragment-B 的后退按钮时,它会转到 Fragment-C。

但是当我点击 Fragment-C 上的后退按钮时,它并没有回到 Fragment-A。 它回到空的背景。如果我想返回 Fragment-A ,我必须再次单击返回按钮。

所以,它似乎没有关闭当前的片段完整。

如何像Android的后退按钮一样完成当前的fragment?

【问题讨论】:

  • 这是什么MainActivity.addFragment(LocalFileBrowserFragment.this, fragment)??。您需要将片段添加到 backstak 并相应地弹出相同的片段
  • 函数addFragment中有添加片段。
  • 将片段添加到什么和一个活动方法??
  • getActivity().onBackPressed();可以这样做

标签: android android-fragments activity-finish


【解决方案1】:

我把代码从getActivity().getFragmentManager().beginTransaction().remove(this).commit();改了

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

并且它可以关闭片段。

【讨论】:

  • getActivity().onBackPressed();认为这将按照您的解释进行。
  • @suomi35 没有。当您需要覆盖 onBackPressed() 时,您将面临这种实现的问题
  • @ViswanathLekshmanan 我认为这应该是一个答案而不是评论。此外,还有公认的答案。
  • 它也关闭了Activity!只需要关闭片段。
  • @FranciscoRomero,我想,Le_Enot 是对的。如果您在活动中覆盖onBackPressed,您将获得另一种行为。例如,如果您在可以在网页中向后移动的 Fragment 中使用 WebView,则不会关闭该 Fragment,而是会移动到上一页。
【解决方案2】:

从片段 A 到 B,将 A 替换为 B,并在 commit() 之前使用 addToBackstack()

现在从 Fragment B 到 C,首先使用popBackStackImmediate(),这将带回 A。现在将 A 替换为 C,就像第一个事务一样。

【讨论】:

  • for usinf popStackImmediate() :-> getView().setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { getActivity().getSupportFragmentManager().popBackStackImmediate() ; return true; } return false; } });
【解决方案3】:

对于那些需要找出简单方法的人

试试getActivity().onBackPressed();

【讨论】:

  • getActivity() 可以多次为空。
  • @ArpitJ。在调用 onAttach() 之前它只是 null,片段不能没有活动。
  • @TamimAttafi 是的,但我指的是旋转或活动已完成等情况,由于某些原因片段实例仍然存在,那么它将返回 null。
  • popBackStack()popBackStackImmediate() 是在不模拟按钮按下的情况下弹出最顶部片段的更直接方式。使用onBackPressed() 触发OnBackPressedCallbacks;如果将来您想专门处理后退按钮按下,则必须切换到 popBackStack()/popBackStackImmediate() 以避免以编程方式触发回调。
  • 你把这段代码放在 Fragment 按钮的 onclick 方法中。
【解决方案4】:

getActivity().onBackPressed 可以满足您的所有需求。它会自动调用父活动中的 onBackPressed 方法。

【讨论】:

    【解决方案5】:

    试试这个:

    public void removeFragment(Fragment fragment){
        android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
        android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
        fragmentTransaction.remove(fragment);
        fragmentTransaction.commit();
    }
    

    【讨论】:

      【解决方案6】:

      这是 Kotlin 的一种做法,我在片段布局中创建了按钮,然后在 onViewCreated 中设置了 onClickListner。

      根据@Viswanath-Lekshmanan 的评论

      override fun onViewCreated(view: View?, savedInstanceState: Bundle?) 
      {
           super.onViewCreated(view, savedInstanceState)
      
           btn_FragSP_back.setOnClickListener {
              activity?.onBackPressed()
          }
      }
      

      【讨论】:

      • 这会关闭活动,而不是片段
      • 如果我们必须双退才能关闭活动,我们该怎么做?
      【解决方案7】:

      试试这个:

      ft.addToBackStack(null);   // ft is FragmentTransaction
      

      因此,当您按下后退键时,当前活动(包含多个片段)将加载前一个片段而不是完成自身。

      【讨论】:

        【解决方案8】:

        你可以试试这个逻辑,因为它对我有用。

        frag_profile profile_fragment = new frag_profile();
        
        boolean flag = false;
        @SuppressLint("ResourceType")
        public void profile_Frag(){
            if (flag == false) {
                FragmentManager manager = getFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                manager.getBackStackEntryCount();
                transaction.setCustomAnimations(R.anim.transition_anim0, R.anim.transition_anim1);
                transaction.replace(R.id.parentPanel, profile_fragment, "FirstFragment");
                transaction.commit();
                flag = true;
            }
        
        }
        
        @Override
        public void onBackPressed() {
            if (flag == true) {
                FragmentManager manager = getFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                manager.getBackStackEntryCount();
                transaction.remove(profile_fragment);
                transaction.commit();
                flag = false;
            }
            else super.onBackPressed();
        }
        

        【讨论】:

          【解决方案9】:
          Button ok= view.findViewById(R.id.btSettingOK);
          Fragment me=this;
          ok.setOnClickListener( new View.OnClickListener(){
              public void onClick(View v){
               getActivity().getFragmentManager().beginTransaction().remove(me).commit();
              }
          });
          

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
          • 这个简单的代码实际上是通过一个确定或关闭按钮来移除当前片段视图。我用它来退出显示为片段的灯光设置面板并返回到活动。抱歉这个技巧,但在 Android 8 下,我认为管理多个 Fragment 不太实用。
          【解决方案10】:

          只需关闭活动

          getActivity().onBackPressed();
          

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
          【解决方案11】:

          如果您需要使用返回按钮更具体地处理操作,您可以使用以下方法:

          view.setFocusableInTouchMode(true);
          view.requestFocus();
          view.setOnKeyListener(new View.OnKeyListener() {
              @Override
              public boolean onKey(View v, int keyCode, KeyEvent event) {
                  if( keyCode == KeyEvent.KEYCODE_BACK )
                  {
                      onCloseFragment();
                      return true;
                  } else {
                      return false;
                  }
              }
          });
          

          【讨论】:

            【解决方案12】:

            在您的片段onCreateView(...) 中,您可以通过调用container.removeView(view); 来删除视图。 所以如果要移除fragment,那么view应该是onCreateView的返回值,

            例如

                public View onCreateView(...){
                    final View view = inflater.inflate(R.layout.your_fragments_layout,container,false);
                    //Do something
                    finishButton.setOnClickListener(new View.OnClickListener(){
                        @Override
                        public void onClick(View v){
                            container.removeView(view);
                        }
                    });
                    return view;
                }
            

            【讨论】:

              【解决方案13】:

              对于移除当前片段 B 并导航回堆栈(其他片段 A):

              private fun navigateToBackStack() {
                  requireActivity().supportFragmentManager
                      .beginTransaction()
                      .remove(this)
                      .commit()
                  requireActivity().supportFragmentManager.popBackStack()
              }
              

              GL

              【讨论】:

                【解决方案14】:

                如果您在 2020 年需要

                    Objects.requireNonNull(getActivity()).onBackPressed();
                

                【讨论】:

                  【解决方案15】:

                  试试这个

                  getActivity().finish();
                  

                  【讨论】:

                  • 尝试多解释一下你的答案,以便OP和其他人在以后回到这个问题时更容易理解答案
                  • 这会关闭整个活动,而不是片段
                  • 它帮助了我。想了解更多信息的朋友可以google一下。此处官方文档无需复制粘贴。
                  • 如果你使用的是BottomNavigationView,它通常只有一个activity,这个命令将关闭应用程序而不是回到之前的fragment。
                  猜你喜欢
                  • 2017-06-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-12-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多