我正在为我的应用添加一个带有三个片段的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;
}
});
答案 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