避免使用BottomNavigationView再次创建片段

时间:2018-04-12 16:08:45

标签: android android-fragments

我正在为我的应用添加一个带有三个片段的BottomNavigationView。 一切都正常,除了一件事。

在第一个片段中,有一个EditText视图,第二个是ListView,第三个是从服务器中托管的JSON加载的一些文本和图像。

这是我的代码:

bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
          @Override
          public boolean onNavigationItemSelected(@NonNull MenuItem item) {
              int id = item.getItemId();
              switch (id) {
                  case R.id.menu_dash:
                      fragment = new frg_dash();
                      break;
                  case R.id.menu_list:
                      fragment = new frg_list();
                      break;
                  case R.id.menu_info:
                      fragment = new frg_info();        
                      break;
              }
              final FragmentTransaction transaction = fragmentManager.beginTransaction();
              transaction.replace(R.id.contenedor_principal, fragment).commit();

              return true;
          }
      });

问题是每次我使用bottomNavigationView按钮从一个片段转到另一个片段时,Fragment会再次开始执行它。

我正在寻找的结果是,如果第二个片段中的用户是,例如,在ListView的中间,它转到第三个片段并再次返回,ListView继续它的位置。 或者,如果您按下bottomNavigationView中第三个片段的按钮,请不要再次从服务器加载数据。

我想问题是当你点击bottomNavigationView按钮时,会再次创建片段:

 ... switch (id) {
      case R.id.menu_dash:
      fragment = new frg_dash();
      break; ...

但这只是猜测。我想它可以用onCreate,onActivityCreated和onCreateView方法控制,但同样,它们只是我的假设。

我已尝试使用片段的hide()和show()参数,但没有成功......或者我没有很好地应用它

我非常感谢提前帮助。

修改

这是我目前的例子,其中包含与答案相关的所有部分:

public void replaceFragment(Fragment fragment, @Nullable Bundle bundle, boolean popBackStack, boolean findInStack) {

    Log.v("2134", "Dentro");

    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    String tag = fragment.getClass().getName();
    Log.v("2134", "tag:" + tag);
    Fragment parentFragment;
    if (findInStack && fm.findFragmentByTag(tag) != null) {
        parentFragment = fm.findFragmentByTag(tag);
    } else {
        parentFragment = fragment;
    }
    // if user passes the @bundle in not null, then can be added to the fragment
    if (bundle != null) {
        parentFragment.setArguments(bundle);
    } else {
        parentFragment.setArguments(null);
    }
    // this is for the very first fragment not to be added into the back stack.
    if (popBackStack) {
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    } else {
        ft.addToBackStack(parentFragment.getClass().getName() + "");
    }
    ft.replace(R.id.contenedor_principal, parentFragment, tag);
    ft.commit();
    fm.executePendingTransactions();
}

...

bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.menu_panel:
                fragment = new frg_panel();
                break;
            case R.id.menu_promos:
                fragment = new frg_promociones();
                break;
            case R.id.menu_catalogo:
                fragment = new frg_catalogo();
                break;
        }

        replaceFragment(fragment, null, true, true);

        return true;
    }
});

1 个答案:

答案 0 :(得分:4)

使用此代码打开您的片段。您的片段不会每次都创建。如果存在,它将从堆栈中获取相同的片段。

/**
     * replace or add fragment to the container
     *
     * @param fragment pass android.support.v4.app.Fragment
     * @param bundle pass your extra bundle if any
     * @param popBackStack if true it will clear back stack
     * @param findInStack if true it will load old fragment if found
     */
    public void replaceFragment(Fragment fragment, @Nullable Bundle bundle, boolean popBackStack, boolean findInStack) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        String tag = fragment.getClass().getName();
        Fragment parentFragment;
        if (findInStack && fm.findFragmentByTag(tag) != null) {
            parentFragment = fm.findFragmentByTag(tag);
        } else {
            parentFragment = fragment;
        }
        // if user passes the @bundle in not null, then can be added to the fragment
        if (bundle != null)
            parentFragment.setArguments(bundle);
        else parentFragment.setArguments(null);
        // this is for the very first fragment not to be added into the back stack.
        if (popBackStack) {
            fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        } else {
            ft.addToBackStack(parentFragment.getClass().getName() + "");
        }
        ft.replace(R.id.contenedor_principal, parentFragment, tag);
        ft.commit();
        fm.executePendingTransactions();
    }

一样使用它

更新:

如果您的片段是主页或仪表板片段,那么

Fragment f = new YourFragment();
replaceFragment(f, null, true, true); 

否则

Fragment f = new YourFragment();
replaceFragment(f, null, false, true); 

重要此代码不能替代保存片段中的所有状态或变量。此代码很有用,因为它不会再次创建片段实例。

要保存片段中的所有状态和变量以供将来使用,请参阅此answer