将Android Fragments保存到导航抽屉中

5

在我的程序中,我有一些片段(Fragments),我可以通过点击每个片段并使用此代码替换它。我的问题是:这些片段加载速度较慢,每次点击片段后都会创建一个新的片段,导致再次加载。如何保存片段内容或状态并防止重新加载?

@Override
    public void onNavigationDrawerItemSelected(int position) {
        Fragment fragment = null;
        switch (position) {
            case 0:
                fragment = new InfoFragment();
                break;
            case 1:
                fragment = new ParentOtoFragment();
                break;
            case 2:
                fragment = new ParentProFragment();
                break;
            case 3:
                fragment = new SupportFragment();
                break;
            case 4:
                fragment = new AboutFragment();
                break;
        }
        if (fragment != null){
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.container,fragment).commit();
        }
    }

更新POST请求

@Vikram Ezhil回复了这个话题之后,我将fragmentsfragmentTAG放入构造函数中,并将@Vikram Ezhil的代码更改为以下代码,我的问题得到解决。

@Override
   public void onNavigationDrawerItemSelected(int position) {
       FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
       fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

       if (getSupportFragmentManager().findFragmentByTag(fragmentTAGS[position]) == null) {
           fragmentTransaction.add(R.id.container, fragments[position], fragmentTAGS[position]);
       }
       for (int i = 0; i < fragments.length; i++) {
           if (i == position) {
               fragmentTransaction.show(fragments[i]);
           } else {
               if (getSupportFragmentManager().findFragmentByTag(fragmentTAGS[position]) != null) {
                   fragmentTransaction.hide(fragments[i]);
               }
           }
       }
       fragmentTransaction.commit();
   }
2个回答

6
为了防止每次从导航抽屉中点击一个项目时都重新创建碎片,您需要使用:
fragmentTransaction.add(R.id.container,fragment).commit();

替代

fragmentTransaction.replace(R.id.container,fragment).commit();

然而,当您添加片段而不是替换它们时,需要进行一些额外的工作。

  1. You need to make sure the the same fragment is not added more than once. You can place a fragment TAG and check if the TAG exists before adding a fragment. Example,

    if (getFragmentManager().findFragmentByTag("fragment1_tag") == null)
    {
        fragmentTransaction.add(R.id.container, fragment1, "fragment1_tag");
    }
    
  2. You need to hide the fragments which are not shown, since when you start adding fragments they will be overlapping with each other on screen.

    if (getFragmentManager().findFragmentByTag("fragment1_tag") != null)
    {
        fragmentTransaction.hide(fragment1);
    }
    
  3. Use interface methods whenever you want to update a specific part in a fragment. I will not go in depth into this, since this is altogether a different topic.

  4. Make sure your fragments are not over-lapped once the application is killed by the android OS to allocate memory for other apps (check out this post for more info).

还有一些建议-根据您的代码,您只有一个片段变量,并将其用于所有5个屏幕。我建议您为5个屏幕分别设置片段变量并将其保存在数组中。

原因是这样会更容易和通用地控制添加、隐藏、显示片段。例如,

InfoFragment fragment1 = new InfoFragment();
ParentOtoFragment fragment2 = new ParentOtoFragment();
ParentProFragment fragment3 = new ParentProFragment();
SupportFragment fragment4 = new SupportFragment();
AboutFragment fragment5 = new AboutFragment();

Fragment[] fragments = new Fragment[]{fragment1,fragment2,fragment3,fragment4,fragment5};
String[] fragmentTAGS = new String[]{"fragment1_tag","fragment2_tag","fragment3_tag","fragment4_tag","fragment5_tag"};

现在使用上述代码,您可以根据导航抽屉中所选项点击的位置来切换片段。
@Override
public void onNavigationDrawerItemSelected(int position) 
{
      // Add the fragments only once if array haven't fragment
      if (getFragmentManager().findFragmentByTag(fragmentTAGS[position]) == null)
      {
          fragmentTransaction.add(R.id.container,fragments[position],fragmentTAGS[position]);
      };

      // Hiding & Showing fragments
      for(int catx=0;catx<fragments.length;catx++)
      {
         if(catx == position)
         {
              fragmentTransaction.show(fragments[catx]);
         }
         else
         {
              // Check if the fragment is added and then hide it
              if (getFragmentManager().findFragmentByTag(fragmentTAGS[catx]) != null)
              {
                  fragmentTransaction.hide(fragments[catx]);
              };
         };
      };

      fragmentTransaction.commit();
};

-1

基于之前的答案,我开发了以下解决方案,希望能帮到某些人:

1.声明一个包含所有片段的数组:

private Fragment[] fragments = new Fragment[] { new frag1(), new frag2()};

2.当onNavigationItemSelected触发事件时:

        Fragment fragment = null;
        switch (itemId) {
            case R.id.nav_frag1:
                fragment = fragments[0];
                break;
            case R.id.nav_frag2:
                fragment = fragments[1];
                break;
            default:
                return;
        }

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.content_main, fragment);
        ft.commit();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接