Reputation: 635
I have a navigation view with some items in it, and when one item is pressed it will go to that fragment. For example, if you press the "Home" item, on the drawer, it will bring up the home fragment.
navigationView = (NavigationView)findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.home_id:
HomeFragment homeFragment = (HomeFragment) fragmentManager.findFragmentByTag("Home");
if (homeFragment == null)
homeFragment = new HomeFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.Main, homeFragment, "Home");
fragmentTransaction.commit();
getSupportActionBar().setTitle("Home");
item.setChecked(true);
drawerLayout.closeDrawers();
break;
case R.id.chat_id:
ChatFragment chatFragment = (ChatFragment) fragmentManager.findFragmentByTag("Chat");
if (chatFragment == null)
chatFragment = new ChatFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.Main, chatFragment, "Chat");
fragmentTransaction.commit();
getSupportActionBar().setTitle("Chat");
item.setChecked(true);
drawerLayout.closeDrawers();
break;
}
}
}
So what I think is happening is that when I am using the replace()
method, it is destroying the chat fragment. What if I have data on the chat fragment, and I want to make sure the data does not go away when I change fragments.
In the ChatFragment
class I have put this override method:
@Override
public void onSaveInstanceState(Bundle outState)
{
Log.d("CHATFRAG", "onSaveInstanceState: been called ");
super.onSaveInstanceState(outState);
outState.putString("textView",textView.getText().toString());
//Save the fragment's state here
}
Now when I switch between fragments in my app, this method does not get called, which means the fragment is being destroyed.
Is there an alternative way where I can swap the current fragment that is on screen, with the desired fragment(without destroying both)? I will be having more fragments (up to ten), is there an optimised solution that will not require duplicate code?
Upvotes: 4
Views: 13323
Reputation: 2814
Although I think Ravi Rupareliya's answer is the best choice (using .add
), I'll share another way I think might work.
You can add two FrameLayout
on top of each other, .add
a Fragment
into both, and then alternate their visibility.
Upvotes: 1
Reputation: 35569
you are replacing fragment with other, so first one will get distroyed. If you dont want it to destroy you need to add
it instead of replace
fragmentTransaction.add(R.id.Main, homeFragment, "Home");
Upvotes: 12
Reputation: 5597
You can create your fragments in advance, for instance in your activity's onCreate()
method:
private HomeFragment homeFragment;
private ChatFragment chatFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
homeFragment = new HomeFragment();
chatFragment = new ChatFragment();
}
Then in your navigation code:
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.home_id:
if (homeFragment == null)
homeFragment = new HomeFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.Main, homeFragment, "Home");
fragmentTransaction.commit();
getSupportActionBar().setTitle("Home");
item.setChecked(true);
drawerLayout.closeDrawers();
break;
case R.id.chat_id:
if (chatFragment == null)
chatFragment = new ChatFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.Main, chatFragment, "Chat");
fragmentTransaction.commit();
getSupportActionBar().setTitle("Chat");
item.setChecked(true);
drawerLayout.closeDrawers();
break;
}
}
Upvotes: 3