|
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; |
|
} |
|
} |