【问题标题】:Replacing a fragment with another fragment inside activity group用活动组内的另一个片段替换片段
【发布时间】:2023-04-11 09:33:02
【问题描述】:

我在组活动中有一个片段,我想用另一个片段替换它:

FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();

当它作为一个单独的项目完成而不使用活动组时它工作正常,每件事在 log cat 中都工作正常,因为控制进入 getview(),但是没有视图是可见的,甚至没有出现任何异常,我想要这本书细节片段被部分细节片段替换。

图书详细信息片段的 xml 具有 id book_description_fragment,章节描述片段的 xml 具有 id section_description_fragment。

上面的代码在一个项目的onClick方法中,我希望当用户在水平滚动视图中点击一个项目时,片段会发生变化。

【问题讨论】:

    标签: java android android-fragments


    【解决方案1】:

    在 XML 中硬编码的片段无法替换。如果您需要用另一个片段替换片段,首先应该动态添加它们。

    注意:R.id.fragment_container 是您在将片段带到的活动中选择的布局或容器。

    // Create new fragment and transaction
    Fragment newFragment = new ExampleFragment();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    
    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack if needed
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    
    // Commit the transaction
    transaction.commit();
    

    【讨论】:

    • 这种情况下的 R.id.fragment_container 是什么?
    • @Guy,它可以是您希望将片段加载到的任何布局。
    • xml 文件中片段的名称应该是什么?我想动态添加片段,不想要任何静态片段。
    • @RajatMehra 如果要动态添加片段,则根本不必在 XML 中指定片段。您可以使用容器视图。请再次阅读答案。
    • @Ahmed 原因在于,根据架构,系统将每个 标签替换为相应片段的onCreateView() 提供的视图(组)。因此,正如您可以假设的那样,对片段的任何引用实际上都在视图级别丢失了。因此,您基本上不能替换片段,而是可以手动删除容器中现在存在的视图,并在需要时将片段放在那里。
    【解决方案2】:

    请看这个Question

    您只能替换“动态添加的片段”。

    所以,如果要添加动态片段,请参阅this 示例。

    【讨论】:

    • 嗨。我发现了解决方案,实际上我没有将片段的内容放在布局中,而是将另一个片段用于前一个片段的内容
    • 不,我想用新片段替换整个片段。
    • @Lion Heart,您能否详细说明您找到的解决方案?
    • 链接已失效:/
    【解决方案3】:

    我已经用完美的方法来管理片段 替换生命周期

    它只会用一个新的片段替换当前片段,如果它不一样并且它不在后台堆栈中(在这种情况下它会弹出它)。

    它包含几个选项,就像您希望将片段保存在后台堆栈中一样。

    => See Gist here

    使用此活动和单个活动,您可能希望将其添加到活动中:

    @Override
    public void onBackPressed() {
        int fragments = getSupportFragmentManager().getBackStackEntryCount();
        if (fragments == 1) {
                finish();
                return;
        }
    
        super.onBackPressed();
    }
    

    【讨论】:

    【解决方案4】:

    在 android.support.v4 中使用以下代码

    FragmentTransaction ft1 = getFragmentManager().beginTransaction();
    WebViewFragment w1 = new WebViewFragment();
    w1.init(linkData.getLink());
    ft1.addToBackStack(linkData.getName());
    ft1.replace(R.id.listFragment, w1);
    ft1.commit();
    

    【讨论】:

      【解决方案5】:

      在 v4 中使用此代码

       ExampleFragment newFragment = new ExampleFragment();     
       FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
       // Replace whatever is in the fragment_container view with this fragment,  
       // and add the transaction to the back stack so the user can navigate back   
       transaction.replace(R.id.container, newFragment);
       transaction.addToBackStack(null);  
       // Commit the transaction   
       transaction.commit();
      

      【讨论】:

        【解决方案6】:

        使用 ViewPager。这对我有用。

        final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager); 
        button = (Button)result.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager.setCurrentItem(1);
            }
        });
        

        【讨论】:

          【解决方案7】:

          希望你做得很好。当我开始使用 Android Fragments 时,我也遇到了同样的问题,然后我读到了 1-如何与其他片段切换。 2-如果Fragment container没有任何片段,如何添加片段。

          然后经过一些研发,我创建了一个可以帮助我到现在的许多项目的函数,我仍在使用这个简单的函数。

          public void switchFragment(BaseFragment baseFragment) {
              try {
                  FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                  ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
                  if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
                      ft.add(R.id.home_frame, baseFragment);
                  } else {
                      ft.replace(R.id.home_frame, baseFragment);
                  }
                  ft.addToBackStack(null);
                  ft.commit();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          

          享受你的代码时间:)

          【讨论】:

          • 为什么必须将片段事务代码包装在 try catch 中并出现一般异常?
          【解决方案8】:

          您可以使用简单的代码进行交易

          Fragment newFragment = new MainCategoryFragment();
          FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
          ft.replace(R.id.content_frame_NavButtom, newFragment);
          ft.commit(); 
          

          【讨论】:

            【解决方案9】:

            您可以使用此代码

            ((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();
            

            或者你可以使用代码

            YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);
            
                    if (fragments==null) {
                        getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
                    }
            

            【讨论】:

              【解决方案10】:

              我在单行代码中动态更改片段
              它适用于任何 SDK 版本和 androidx
              我使用导航为BottomNavigationView

                  BottomNavigationView btn_nav;
                  FragmentFirst fragmentFirst;
                  FragmentSecond fragmentSecond;
              
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_search);
                      fragmentFirst = new FragmentFirst();
                      fragmentSecond = new FragmentSecond ();
                      changeFragment(fragmentFirst); // at first time load the fragmentFirst
                      btn_nav = findViewById(R.id.bottomNav);
                      btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
                          @Override
                          public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                              switch(menuItem.getItemId()){
                                  case R.id.menu_first_frag:
                                      changeFragment(fragmentFirst); // change fragmentFirst
                                      break;
                                  case R.id.menu_second_frag:
                                      changeFragment(fragmentSecond); // change fragmentSecond
                                      break;
                                      default:
                                          Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
                              }
                              return true;
                          }
                      });
                  }
              
              public void changeFragment(Fragment fragment) {
                      getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
                  }
              

              【讨论】:

                【解决方案11】:

                在 kotlin 中你可以这样做:

                // instantiate the new fragment
                val fragment: Fragment = ExampleFragment()
                
                val transaction = supportFragmentManager.beginTransaction()
                transaction.replace(R.id.book_description_fragment, fragment)
                transaction.addToBackStack("transaction_name")
                // Commit the transaction
                transaction.commit()
                

                【讨论】:

                  【解决方案12】:

                  如果您尝试从另一个片段更改片段,这将起作用。

                  Objects.requireNonNull(getActivity()).getSupportFragmentManager()
                  .beginTransaction()
                  .replace(R.id.home_fragment_container,new NewFragment())
                  

                  注意如上述答案所述,您需要有动态片段。

                  【讨论】:

                    【解决方案13】:

                    你可以使用fragment-ktx

                    // If you are in fragmet
                    childFragmentManager.beginTransaction()
                    
                    // or if you are in activiry
                    supportFragmentManager.beginTransaction()
                    
                    // Create and commit a new transaction
                    supportFragmentManager.commit {
                      setReorderingAllowed(true)
                      // Replace whatever is in the fragment_container view with this fragment
                      replace<ExampleFragment>(R.id.fragment_container)
                    }
                    

                    【讨论】:

                      【解决方案14】:

                      要使用另一个片段替换片段,请注意,R.id.fragment 来自您为 XML 中片段的第一个标记提供的 id。

                      barAudioPlaying.setOnClickListener(view -> {
                                      getActivity().getSupportFragmentManager()
                                              .beginTransaction()
                                              .replace(R.id.fragment,new HomeFragment())
                                              .commit();
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-11-18
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-08-19
                        • 1970-01-01
                        • 2017-06-12
                        相关资源
                        最近更新 更多