如何在更改选项卡时停止重新加载片段?
How to Stop Fragment from Reloading When Changing Tabs?
我有一个 Activity
和一个 BottomNavigationView
,它由 4 个 Fragments
组成,每当我更改标签时 Fragments
重新加载,这是我的 Activity
的代码
public class MainHomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_home);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull @NotNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()){
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_list:
selectedFragment = new UsersFragment();
break;
case R.id.nav_profile:
selectedFragment = new ProfileFragment();
break;
case R.id.nav_settings:
selectedFragment = new SettingsFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
return true;
}
};
}
在 Fragments
中,我从 parse
加载数据
我知道我犯的错误是每当我切换标签时我都会创建一个 Fragment
的新实例,但我不知道如何修复它或从哪里开始
我看到有人说在这种情况下应该使用 ViewPagerAdapter
,但我无法找到一个可以正确解释它的地方。
如有任何帮助,我们将不胜感激!
而不是 replacing
片段,使用 add/remove
并创建一种添加和删除片段的机制堆栈,也不推荐,但出于问题的考虑,您可以创建一个单例片段,而不是使用 new
关键字 everything 选项卡已更改,您可以看看 pageOffSet
companion object{
private lateinit var INSTANCE?: HomeFragment() = null
}
fun getInstance(): HomeFragment(){
if(INSTANCE == null){
INSTANCE = HomeFragment()
}
return INSTANCE
}
正如我们所知,当我们使用 BottomNavigationView
切换页面时,ViewPager
会重新创建片段。我知道如何防止这种情况,使用以下 2 个选项之一:
- 正如我所看到的,您的片段数量很少且固定,添加您的
onCreate()
的
MainHomeActivity.java
:
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit); //limit is a fixed integer
- 使用 FragmentPagerAdapter 作为
ViewPager
的一部分。 (示例在 link 中提供)
更新
在@moalzoabi 的案例中,第二个选项有效。按照这个 .
Here's an article 完美且详细地描述了您的案例。
基本上,它在内存中为每个选项卡创建一个片段,并将它们作为局部变量保存在 activity:
final Fragment fragment1 = new HomeFragment();
final Fragment fragment2 = new DashboardFragment();
final Fragment fragment3 = new NotificationsFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;
您将所有 3 个片段添加到管理器,但隐藏了其中的 2 个,因此只有 1 个可见:
fm.beginTransaction().add(R.id.main_container, fragment3, "3").hide(fragment3).commit();
fm.beginTransaction().add(R.id.main_container, fragment2, "2").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container,fragment1, "1").commit();
您实现 BottomNavigationView
的 OnNavigationItemSelectedListener
,检查按下了哪个项目,然后在隐藏前一个片段的同时显示该片段:
case R.id.navigation_dashboard:
fm.beginTransaction().hide(active).show(fragment2).commit();
active = fragment2;
我有一个 Activity
和一个 BottomNavigationView
,它由 4 个 Fragments
组成,每当我更改标签时 Fragments
重新加载,这是我的 Activity
的代码
public class MainHomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_home);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull @NotNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()){
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_list:
selectedFragment = new UsersFragment();
break;
case R.id.nav_profile:
selectedFragment = new ProfileFragment();
break;
case R.id.nav_settings:
selectedFragment = new SettingsFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
return true;
}
};
}
在 Fragments
中,我从 parse
加载数据
我知道我犯的错误是每当我切换标签时我都会创建一个 Fragment
的新实例,但我不知道如何修复它或从哪里开始
我看到有人说在这种情况下应该使用 ViewPagerAdapter
,但我无法找到一个可以正确解释它的地方。
如有任何帮助,我们将不胜感激!
而不是 replacing
片段,使用 add/remove
并创建一种添加和删除片段的机制堆栈,也不推荐,但出于问题的考虑,您可以创建一个单例片段,而不是使用 new
关键字 everything 选项卡已更改,您可以看看 pageOffSet
companion object{
private lateinit var INSTANCE?: HomeFragment() = null
}
fun getInstance(): HomeFragment(){
if(INSTANCE == null){
INSTANCE = HomeFragment()
}
return INSTANCE
}
正如我们所知,当我们使用 BottomNavigationView
切换页面时,ViewPager
会重新创建片段。我知道如何防止这种情况,使用以下 2 个选项之一:
- 正如我所看到的,您的片段数量很少且固定,添加您的
onCreate()
的
MainHomeActivity.java
:
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit); //limit is a fixed integer
- 使用 FragmentPagerAdapter 作为
ViewPager
的一部分。 (示例在 link 中提供)
更新
在@moalzoabi 的案例中,第二个选项有效。按照这个
Here's an article 完美且详细地描述了您的案例。
基本上,它在内存中为每个选项卡创建一个片段,并将它们作为局部变量保存在 activity:
final Fragment fragment1 = new HomeFragment();
final Fragment fragment2 = new DashboardFragment();
final Fragment fragment3 = new NotificationsFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;
您将所有 3 个片段添加到管理器,但隐藏了其中的 2 个,因此只有 1 个可见:
fm.beginTransaction().add(R.id.main_container, fragment3, "3").hide(fragment3).commit();
fm.beginTransaction().add(R.id.main_container, fragment2, "2").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container,fragment1, "1").commit();
您实现 BottomNavigationView
的 OnNavigationItemSelectedListener
,检查按下了哪个项目,然后在隐藏前一个片段的同时显示该片段:
case R.id.navigation_dashboard:
fm.beginTransaction().hide(active).show(fragment2).commit();
active = fragment2;