英文:
Fragments overlapping in Android
问题
private void loadFragment(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (alreadyOpened[currentIndex]) {
ft.replace(R.id.fragment_container, fragments.get(currentIndex));
} else {
fragments.add(currentIndex, fragment);
alreadyOpened[currentIndex] = true;
ft.replace(R.id.fragment_container, fragment);
}
ft.addToBackStack(null);
ft.commit();
}
英文:
I'm trying to switch between fragments without losing the previous contents, so I decided to implement this way to do it:
private void loadFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().hide(fragment);
if (!alreadyOpened[currentIndex]) {
alreadyOpened[currentIndex] = true;
fragmentManager.beginTransaction().add(R.id.fragment_container,fragment).commit();
} else {
fragmentManager.beginTransaction().show(fragment).commit();
}
}
With this method I check if a fragment has been already opened: if yes, I show it, if not I add it. Then I declare it as "alreadyOpened". The problem is that when I switch between fragments I see all the three fragments overlapping. How can I solve it?
This is the menu bar when I invoke the loadFragment method:
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.bbn_item1:
currentIndex = 0;
loadFragment(new HomeFragment());
return true;
case R.id.bbn_item2:
currentIndex = 1;
loadFragment(new PopularFragment());
return true;
case R.id.bbn_item3:
currentIndex = 2;
loadFragment(new PlayingFragment());
return true;
}
return false;
}
};
EDIT: new code
List<Fragment> fragments = new ArrayList<>();
private void loadFragment(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (alreadyOpened[currentIndex]) {
ft.replace(R.id.fragment_container, fragments.get(currentIndex));
} else {
fragments.add(currentIndex, fragment);
alreadyOpened[currentIndex] = true;
ft.replace(R.id.fragment_container, fragment);
}
ft.addToBackStack(null);
ft.commit();
}
答案1
得分: 1
你不应该在每次导航点击时都创建新的片段。在某处创建一次,然后将它们保存在List<Fragment> fragments
数组中。之后使用fragmentManager.beginTransaction().replace(R.id.fragment_layout, fragment);
,这里是一个小例子:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left); //可选
ft.replace(R.id.fragment_layout, fragments.get(selectedFragment));
ft.addToBackStack(null);
ft.commit();
从你的onNavigationItemSelected
中发送selectedFragment
变量,并在fragments
列表中匹配位置。
编辑:
这样怎么样:
public HomeFragment homeFragment;
public PopularFragment popularFragment;
public PlayingFragment playingFragment;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.bbn_item1:
if(homeFragment == null){ homeFragment =new HomeFragment();}
loadFragment(homeFragment )
return true;
case R.id.bbn_item2:
if(popularFragment == null){ popularFragment =new PopularFragment();}
loadFragment(popularFragment)
return true;
case R.id.bbn_item3:
if(playingFragment == null){ playingFragment =new PlayingFragment();}
loadFragment(playingFragment);
return true;
}
return false;
}
};
public void loadFragment(Fragment fragment){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left); //可选
ft.replace(R.id.fragment_layout, fragment);
ft.addToBackStack(null);
ft.commit();
}
英文:
You should not created new Fragments on every navigation click. created once somewhere and save them in List<Fragment> fragments
array. and after that use fragmentManager.beginTransaction().replace(R.id.fragment_layout, fragment);
here is little example:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left); //optional
ft.replace(R.id.fragment_layout, fragments.get(selectedFragment));
ft.addToBackStack(null);
ft.commit();
From your onNavigationItemSelected
send selectedFragment
variable, and match the position in the fragments
list.
Edit:
how about this:
public HomeFragment homeFragment;
public PopularFragment popularFragment;
public PlayingFragment playingFragment;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.bbn_item1:
if(homeFragment == null){ homeFragment =new HomeFragment();}
loadFragment(homeFragment )
return true;
case R.id.bbn_item2:
if(homeFragment == null){ popularFragment =new PopularFragment();}
loadFragment(popularFragment)
return true;
case R.id.bbn_item3:
if(homeFragment == null){ playingFragment =new PlayingFragment();}
loadFragment(playingFragment);
return true;
}
return false;
}
};
public void loadFragment(Fragment fragment){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left); //optional
ft.replace(R.id.fragment_layout, fragment);
ft.addToBackStack(null);
ft.commit();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论