From 97490d5c0b770aef6ef15ec4d2f390e5cd205b66 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Sun, 4 Jul 2021 02:40:38 +0900 Subject: [PATCH] Add back screen transitions with option to disable them --- .../customviews/BarinstaFragmentNavigator.kt | 90 +++++++++++++++++++ .../customviews/BarinstaNavHostFragment.kt | 14 +++ ...ragmentNavigatorWithDefaultAnimations.java | 75 ---------------- .../NavHostFragmentWithDefaultAnimations.java | 60 ------------- .../settings/GeneralPreferencesFragment.java | 9 ++ .../fragments/settings/PreferenceKeys.kt | 1 + app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/values/strings.xml | 1 + 8 files changed, 116 insertions(+), 136 deletions(-) create mode 100644 app/src/main/java/awais/instagrabber/customviews/BarinstaFragmentNavigator.kt create mode 100644 app/src/main/java/awais/instagrabber/customviews/BarinstaNavHostFragment.kt delete mode 100644 app/src/main/java/awais/instagrabber/customviews/FragmentNavigatorWithDefaultAnimations.java delete mode 100644 app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java diff --git a/app/src/main/java/awais/instagrabber/customviews/BarinstaFragmentNavigator.kt b/app/src/main/java/awais/instagrabber/customviews/BarinstaFragmentNavigator.kt new file mode 100644 index 00000000..1220c0d6 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/customviews/BarinstaFragmentNavigator.kt @@ -0,0 +1,90 @@ +package awais.instagrabber.customviews + +import android.content.Context +import androidx.fragment.app.FragmentManager +import androidx.navigation.NavBackStackEntry +import androidx.navigation.NavOptions +import androidx.navigation.Navigator +import androidx.navigation.fragment.FragmentNavigator +import androidx.navigation.navOptions +import awais.instagrabber.R +import awais.instagrabber.fragments.settings.PreferenceKeys +import awais.instagrabber.utils.Utils + +private val defaultNavOptions = navOptions { + anim { + enter = R.anim.slide_in_right + exit = R.anim.slide_out_left + popEnter = android.R.anim.slide_in_left + popExit = android.R.anim.slide_out_right + } +} + +private val emptyNavOptions = navOptions {} + +/** + * Needs to replace FragmentNavigator and replacing is done with name in annotation. + * Navigation method will use defaults for fragments transitions animations. + */ +@Navigator.Name("fragment") +class BarinstaFragmentNavigator( + context: Context, + fragmentManager: FragmentManager, + containerId: Int +) : FragmentNavigator(context, fragmentManager, containerId) { + + override fun navigate( + entries: List, + navOptions: NavOptions?, + navigatorExtras: Navigator.Extras? + ) { + val disableTransitions = Utils.settingsHelper.getBoolean(PreferenceKeys.PREF_DISABLE_SCREEN_TRANSITIONS) + if (disableTransitions) { + super.navigate(entries, navOptions, navigatorExtras) + return + } + // this will try to fill in empty animations with defaults when no shared element transitions + // https://developer.android.com/guide/navigation/navigation-animate-transitions#shared-element + val hasSharedElements = navigatorExtras != null && navigatorExtras is Extras + val navOptions1 = if (hasSharedElements) navOptions else navOptions.fillEmptyAnimationsWithDefaults() + super.navigate(entries, navOptions1, navigatorExtras) + } + + private fun NavOptions?.fillEmptyAnimationsWithDefaults(): NavOptions = + this?.copyNavOptionsWithDefaultAnimations() ?: defaultNavOptions + + private fun NavOptions.copyNavOptionsWithDefaultAnimations(): NavOptions = let { originalNavOptions -> + navOptions { + launchSingleTop = originalNavOptions.shouldLaunchSingleTop() + popUpTo(originalNavOptions.popUpToId) { + inclusive = originalNavOptions.isPopUpToInclusive() + saveState = originalNavOptions.shouldPopUpToSaveState() + } + originalNavOptions.popUpToRoute?.let { + popUpTo(it) { + inclusive = originalNavOptions.isPopUpToInclusive() + saveState = originalNavOptions.shouldPopUpToSaveState() + } + } + restoreState = originalNavOptions.shouldRestoreState() + anim { + enter = + if (originalNavOptions.enterAnim == emptyNavOptions.enterAnim) defaultNavOptions.enterAnim + else originalNavOptions.enterAnim + exit = + if (originalNavOptions.exitAnim == emptyNavOptions.exitAnim) defaultNavOptions.exitAnim + else originalNavOptions.exitAnim + popEnter = + if (originalNavOptions.popEnterAnim == emptyNavOptions.popEnterAnim) defaultNavOptions.popEnterAnim + else originalNavOptions.popEnterAnim + popExit = + if (originalNavOptions.popExitAnim == emptyNavOptions.popExitAnim) defaultNavOptions.popExitAnim + else originalNavOptions.popExitAnim + } + } + } + + private companion object { + private const val TAG = "FragmentNavigator" + } +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/customviews/BarinstaNavHostFragment.kt b/app/src/main/java/awais/instagrabber/customviews/BarinstaNavHostFragment.kt new file mode 100644 index 00000000..24979a95 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/customviews/BarinstaNavHostFragment.kt @@ -0,0 +1,14 @@ +package awais.instagrabber.customviews + +import androidx.navigation.NavHostController +import androidx.navigation.fragment.NavHostFragment + +class BarinstaNavHostFragment : NavHostFragment() { + override fun onCreateNavHostController(navHostController: NavHostController) { + super.onCreateNavHostController(navHostController) + navHostController.navigatorProvider.addNavigator( + // this replaces FragmentNavigator + BarinstaFragmentNavigator(requireContext(), childFragmentManager, id) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/customviews/FragmentNavigatorWithDefaultAnimations.java b/app/src/main/java/awais/instagrabber/customviews/FragmentNavigatorWithDefaultAnimations.java deleted file mode 100644 index 358e34d8..00000000 --- a/app/src/main/java/awais/instagrabber/customviews/FragmentNavigatorWithDefaultAnimations.java +++ /dev/null @@ -1,75 +0,0 @@ -package awais.instagrabber.customviews; - -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentManager; -import androidx.navigation.NavDestination; -import androidx.navigation.NavOptions; -import androidx.navigation.Navigator; -import androidx.navigation.fragment.FragmentNavigator; - -import awais.instagrabber.R; - -@Navigator.Name("fragment") -public class FragmentNavigatorWithDefaultAnimations extends FragmentNavigator { - - private final NavOptions emptyNavOptions = new NavOptions.Builder().build(); - // private final NavOptions defaultNavOptions = new NavOptions.Builder() - // .setEnterAnim(R.animator.nav_default_enter_anim) - // .setExitAnim(R.animator.nav_default_exit_anim) - // .setPopEnterAnim(R.animator.nav_default_pop_enter_anim) - // .setPopExitAnim(R.animator.nav_default_pop_exit_anim) - // .build(); - - private final NavOptions defaultNavOptions = new NavOptions.Builder() - .setEnterAnim(R.anim.slide_in_right) - .setExitAnim(R.anim.slide_out_left) - .setPopEnterAnim(android.R.anim.slide_in_left) - .setPopExitAnim(android.R.anim.slide_out_right) - .build(); - - public FragmentNavigatorWithDefaultAnimations(@NonNull final Context context, - @NonNull final FragmentManager manager, - final int containerId) { - super(context, manager, containerId); - } - - @Nullable - @Override - public NavDestination navigate(@NonNull final Destination destination, - @Nullable final Bundle args, - @Nullable final NavOptions navOptions, - @Nullable final Navigator.Extras navigatorExtras) { - // this will try to fill in empty animations with defaults when no shared element transitions are set - // https://developer.android.com/guide/navigation/navigation-animate-transitions#shared-element - final boolean shouldUseTransitionsInstead = navigatorExtras != null; - final NavOptions navOptions1 = shouldUseTransitionsInstead ? navOptions : fillEmptyAnimationsWithDefaults(navOptions); - return super.navigate(destination, args, navOptions1, navigatorExtras); - } - - private NavOptions fillEmptyAnimationsWithDefaults(@Nullable final NavOptions navOptions) { - if (navOptions == null) { - return defaultNavOptions; - } - return copyNavOptionsWithDefaultAnimations(navOptions); - } - - @NonNull - private NavOptions copyNavOptionsWithDefaultAnimations(@NonNull final NavOptions navOptions) { - return new NavOptions.Builder() - .setLaunchSingleTop(navOptions.shouldLaunchSingleTop()) - .setPopUpTo(navOptions.getPopUpTo(), navOptions.isPopUpToInclusive()) - .setEnterAnim(navOptions.getEnterAnim() == emptyNavOptions.getEnterAnim() - ? defaultNavOptions.getEnterAnim() : navOptions.getEnterAnim()) - .setExitAnim(navOptions.getExitAnim() == emptyNavOptions.getExitAnim() - ? defaultNavOptions.getExitAnim() : navOptions.getExitAnim()) - .setPopEnterAnim(navOptions.getPopEnterAnim() == emptyNavOptions.getPopEnterAnim() - ? defaultNavOptions.getPopEnterAnim() : navOptions.getPopEnterAnim()) - .setPopExitAnim(navOptions.getPopExitAnim() == emptyNavOptions.getPopExitAnim() - ? defaultNavOptions.getPopExitAnim() : navOptions.getPopExitAnim()) - .build(); - } -} diff --git a/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java b/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java deleted file mode 100644 index a67166cf..00000000 --- a/app/src/main/java/awais/instagrabber/customviews/NavHostFragmentWithDefaultAnimations.java +++ /dev/null @@ -1,60 +0,0 @@ -// package awais.instagrabber.customviews; -// -// import android.os.Bundle; -// -// import androidx.annotation.NavigationRes; -// import androidx.annotation.NonNull; -// import androidx.annotation.Nullable; -// import androidx.navigation.NavController; -// import androidx.navigation.Navigator; -// import androidx.navigation.fragment.FragmentNavigator; -// import androidx.navigation.fragment.NavHostFragment; -// -// public class NavHostFragmentWithDefaultAnimations extends NavHostFragment { -// private static final String KEY_GRAPH_ID = "android-support-nav:fragment:graphId"; -// private static final String KEY_START_DESTINATION_ARGS = -// "android-support-nav:fragment:startDestinationArgs"; -// private static final String KEY_NAV_CONTROLLER_STATE = -// "android-support-nav:fragment:navControllerState"; -// private static final String KEY_DEFAULT_NAV_HOST = "android-support-nav:fragment:defaultHost"; -// -// @NonNull -// public static NavHostFragment create(@NavigationRes int graphResId) { -// return create(graphResId, null); -// } -// -// @NonNull -// public static NavHostFragment create(@NavigationRes int graphResId, -// @Nullable Bundle startDestinationArgs) { -// Bundle b = null; -// if (graphResId != 0) { -// b = new Bundle(); -// b.putInt(KEY_GRAPH_ID, graphResId); -// } -// if (startDestinationArgs != null) { -// if (b == null) { -// b = new Bundle(); -// } -// b.putBundle(KEY_START_DESTINATION_ARGS, startDestinationArgs); -// } -// -// final NavHostFragmentWithDefaultAnimations result = new NavHostFragmentWithDefaultAnimations(); -// if (b != null) { -// result.setArguments(b); -// } -// return result; -// } -// -// @NonNull -// @Override -// protected Navigator createFragmentNavigator() { -// return new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId()); -// } -// -// @Override -// protected void onCreateNavController(@NonNull final NavController navController) { -// super.onCreateNavController(navController); -// navController.getNavigatorProvider() -// .addNavigator(new FragmentNavigatorWithDefaultAnimations(requireContext(), getChildFragmentManager(), getId())); -// } -// } diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java index c8552bd1..73fc94a0 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java @@ -34,6 +34,7 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen screen.addPreference(getDefaultTabPreference(context)); screen.addPreference(getTabOrderPreference(context)); } + screen.addPreference(getDisableScreenTransitionsPreference(context)); screen.addPreference(getUpdateCheckPreference(context)); screen.addPreference(getFlagSecurePreference(context)); screen.addPreference(getSearchFocusPreference(context)); @@ -82,6 +83,14 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen return preference; } + private Preference getDisableScreenTransitionsPreference(@NonNull final Context context) { + final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); + preference.setKey(PreferenceKeys.PREF_DISABLE_SCREEN_TRANSITIONS); + preference.setTitle(R.string.disable_screen_transitions); + preference.setIconSpaceReserved(false); + return preference; + } + private Preference getUpdateCheckPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); preference.setKey(PreferenceKeys.CHECK_UPDATES); diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.kt b/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.kt index a2a9649d..161a4a9b 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.kt +++ b/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.kt @@ -11,6 +11,7 @@ object PreferenceKeys { const val PREF_SHOWN_COUNT_TOOLTIP = "shown_count_tooltip" const val PREF_SEARCH_FOCUS_KEYBOARD = "search_focus_keyboard" const val PREF_AUTO_BACKUP_ENABLED = "auto_backup_enabled" + const val PREF_DISABLE_SCREEN_TRANSITIONS = "disable_screen_transitions" // string prefs const val FOLDER_PATH = "custom_path" diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 5a714857..9a0c155b 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -60,7 +60,7 @@ Share via DM Share linkā€¦ Slide to Cancel + Disable screen transitions