Skip to content

Instantly share code, notes, and snippets.

@erfanegtfi
Created April 16, 2020 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erfanegtfi/4a733b400978efb4a404e0af0b4c3819 to your computer and use it in GitHub Desktop.
Save erfanegtfi/4a733b400978efb4a404e0af0b4c3819 to your computer and use it in GitHub Desktop.
keep state of fragments inside fragment navigation. (use add/hide or attach/detach instead of replace)
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.navigation.NavDestination;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigator;
import androidx.navigation.fragment.FragmentNavigator;
@Navigator.Name("keep_state_fragment") //`keep_state_fragment` is used in navigation xml
public class KeepStateNavigator extends FragmentNavigator {
private FragmentManager manager;
private Context context;
private int containerId;
public KeepStateNavigator(@NonNull Context context, @NonNull FragmentManager manager, int containerId) {
super(context, manager, containerId);
this.manager = manager;
this.context = context;
this.containerId = containerId;
}
@Nullable
@Override
public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {
String tag = String.valueOf(destination.getId());
FragmentTransaction transaction = manager.beginTransaction();
boolean initialNavigate = false;
Fragment currentFragment = manager.getPrimaryNavigationFragment();
if (currentFragment != null) {
transaction.hide(currentFragment);//or detach
} else {
initialNavigate = true;
}
Fragment fragment = manager.findFragmentByTag(tag);
if (fragment == null) {
String className = destination.getClassName();
fragment = manager.getFragmentFactory().instantiate(context.getClassLoader(), className);
transaction.add(containerId, fragment, tag);
} else {
transaction.show(fragment);//or attach
}
transaction.setPrimaryNavigationFragment(fragment);
transaction.setReorderingAllowed(true);
transaction.commitNow();
if (initialNavigate)
return destination;
else
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation.xml"
app:startDestination="@id/navigation_home">
<keep_state_fragment
android:id="@+id/navigation_home"
android:name=".HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
</navigation>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment