From c666a6b534d6460bf636403b9438d518bc5bcb0c Mon Sep 17 00:00:00 2001 From: Willow Date: Sun, 25 Feb 2024 16:20:15 +0100 Subject: [PATCH] Better screen transitions (#4285) I mostly took Android 13 transitions and removed the sliding for the "deeper"/background one because "extend" animations are not available until Android 13. Here are the original ones: https://cs.android.com/android/platform/superproject/+/android-13.0.0_r8:frameworks/base/core/res/res/anim/;bpv=1 Initially I've made separate versions fro Android 13+ that are close to the original but I think it's not worth it to keep both. https://github.com/tuskyapp/Tusky/assets/3099142/616fc40c-f944-45b4-bf6f-167f62d30493 --- .../com/keylesspalace/tusky/BaseActivity.java | 15 +++++++---- .../com/keylesspalace/tusky/MainActivity.kt | 3 ++- .../tusky/components/login/LoginActivity.kt | 2 +- .../preference/PreferencesActivity.kt | 8 +++--- .../TabFilterPreferencesFragment.kt | 15 +++++++++++ .../viewthread/ViewThreadFragment.kt | 8 +++--- .../keylesspalace/tusky/fragment/SFragment.kt | 2 +- .../tusky/util/ActivityExensions.kt | 8 ++++-- .../main/res/anim/actitivity_close_enter.xml | 22 ++++++++++++++++ app/src/main/res/anim/activity_close_exit.xml | 25 +++++++++++++++++++ app/src/main/res/anim/activity_open_enter.xml | 23 +++++++++++++++++ app/src/main/res/anim/activity_open_exit.xml | 22 ++++++++++++++++ .../main/res/anim/fast_out_extra_slow_in.xml | 18 +++++++++++++ app/src/main/res/anim/slide_from_left.xml | 6 ----- app/src/main/res/anim/slide_from_right.xml | 6 ----- app/src/main/res/anim/slide_to_left.xml | 6 ----- app/src/main/res/anim/slide_to_right.xml | 6 ----- 17 files changed, 153 insertions(+), 42 deletions(-) create mode 100644 app/src/main/res/anim/actitivity_close_enter.xml create mode 100644 app/src/main/res/anim/activity_close_exit.xml create mode 100644 app/src/main/res/anim/activity_open_enter.xml create mode 100644 app/src/main/res/anim/activity_open_exit.xml create mode 100644 app/src/main/res/anim/fast_out_extra_slow_in.xml delete mode 100644 app/src/main/res/anim/slide_from_left.xml delete mode 100644 app/src/main/res/anim/slide_from_right.xml delete mode 100644 app/src/main/res/anim/slide_to_left.xml delete mode 100644 app/src/main/res/anim/slide_to_right.xml diff --git a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java index 1852946c0..1deb25d9a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java @@ -60,6 +60,7 @@ import java.util.List; import javax.inject.Inject; import static com.keylesspalace.tusky.settings.PrefKeys.APP_THEME; +import static com.keylesspalace.tusky.util.ActivityExtensions.supportsOverridingActivityTransitions; public abstract class BaseActivity extends AppCompatActivity implements Injectable { @@ -78,9 +79,9 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && getIntent().getBooleanExtra(OPEN_WITH_SLIDE_IN, false)) { - overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, R.anim.slide_from_right, R.anim.slide_to_left); - overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, R.anim.slide_from_left, R.anim.slide_to_right); + if (supportsOverridingActivityTransitions() && activityTransitionWasRequested()) { + overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, R.anim.activity_open_enter, R.anim.activity_open_exit); + overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, R.anim.actitivity_close_enter, R.anim.activity_close_exit); } SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); @@ -111,6 +112,10 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab requesters = new HashMap<>(); } + private boolean activityTransitionWasRequested() { + return getIntent().getBooleanExtra(OPEN_WITH_SLIDE_IN, false); + } + @Override protected void attachBaseContext(Context newBase) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(newBase); @@ -189,8 +194,8 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab public void finish() { super.finish(); // if this activity was opened with slide-in, close it with slide out - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE && getIntent().getBooleanExtra(OPEN_WITH_SLIDE_IN, false)) { - overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right); + if (!supportsOverridingActivityTransitions() && activityTransitionWasRequested()) { + overridePendingTransition(R.anim.actitivity_close_enter, R.anim.activity_close_exit); } } diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt b/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt index 0b6e54b3b..92691dfd6 100644 --- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt @@ -109,6 +109,7 @@ import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.reduceSwipeSensitivity import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.startActivityWithSlideInAnimation +import com.keylesspalace.tusky.util.supportsOverridingActivityTransitions import com.keylesspalace.tusky.util.unsafeLazy import com.keylesspalace.tusky.util.updateShortcut import com.keylesspalace.tusky.util.viewBinding @@ -978,7 +979,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje } startActivity(intent) finish() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + if (supportsOverridingActivityTransitions()) { overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, R.anim.explode, R.anim.explode) } else { @Suppress("DEPRECATION") diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt index 06484d245..1cdadd20e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt @@ -126,7 +126,7 @@ class LoginActivity : BaseActivity(), Injectable { override fun finish() { super.finish() if (isAdditionalLogin() || isAccountMigration()) { - overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right) + overridePendingTransition(R.anim.actitivity_close_enter, R.anim.activity_close_exit) } } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt index c608f102a..ac402fddf 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesActivity.kt @@ -115,10 +115,10 @@ class PreferencesActivity : fragment.setTargetFragment(caller, 0) supportFragmentManager.commit { setCustomAnimations( - R.anim.slide_from_right, - R.anim.slide_to_left, - R.anim.slide_from_left, - R.anim.slide_to_right + R.anim.activity_open_enter, + R.anim.activity_open_exit, + R.anim.actitivity_close_enter, + R.anim.activity_close_exit ) replace(R.id.fragment_container, fragment) addToBackStack(null) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt index cb6eeb46e..93fe05cd0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/TabFilterPreferencesFragment.kt @@ -16,7 +16,11 @@ package com.keylesspalace.tusky.components.preference import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.preference.PreferenceFragmentCompat +import com.google.android.material.color.MaterialColors import com.keylesspalace.tusky.R import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.settings.AccountPreferenceDataStore @@ -31,6 +35,17 @@ class TabFilterPreferencesFragment : PreferenceFragmentCompat(), Injectable { @Inject lateinit var accountPreferenceDataStore: AccountPreferenceDataStore + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + // Give view a background color so transitions show up correctly + return super.onCreateView(inflater, container, savedInstanceState).also { view -> + view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.colorBackground)) + } + } + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { makePreferenceScreen { preferenceCategory(R.string.title_home) { category -> diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt index ab7b84020..dc1d91ce3 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadFragment.kt @@ -429,10 +429,10 @@ class ViewThreadFragment : parentFragmentManager.commit { setCustomAnimations( - R.anim.slide_from_right, - R.anim.slide_to_left, - R.anim.slide_from_left, - R.anim.slide_to_right + R.anim.activity_open_enter, + R.anim.activity_open_exit, + R.anim.actitivity_close_enter, + R.anim.activity_close_exit ) replace(R.id.fragment_container, viewEditsFragment, "ViewEditsFragment_$id") addToBackStack(null) diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt b/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt index 73617ae41..8072a684a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.kt @@ -84,7 +84,7 @@ abstract class SFragment : Fragment(), Injectable { override fun startActivity(intent: Intent) { super.startActivity(intent) - requireActivity().overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left) + requireActivity().overridePendingTransition(R.anim.activity_open_enter, R.anim.activity_open_exit) } override fun onAttach(context: Context) { diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ActivityExensions.kt b/app/src/main/java/com/keylesspalace/tusky/util/ActivityExensions.kt index df34fcdf3..bfe27ecd7 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/ActivityExensions.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/ActivityExensions.kt @@ -13,9 +13,13 @@ fun Activity.startActivityWithSlideInAnimation(intent: Intent) { // so we pass a flag that BaseActivity will respect. intent.putExtra(BaseActivity.OPEN_WITH_SLIDE_IN, true) startActivity(intent) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + if (!supportsOverridingActivityTransitions()) { // the old api needs to be called by the activity that starts the transition @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left) + overridePendingTransition(R.anim.activity_open_enter, R.anim.activity_open_exit) } } + +fun supportsOverridingActivityTransitions(): Boolean { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE +} diff --git a/app/src/main/res/anim/actitivity_close_enter.xml b/app/src/main/res/anim/actitivity_close_enter.xml new file mode 100644 index 000000000..2c08910bf --- /dev/null +++ b/app/src/main/res/anim/actitivity_close_enter.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/app/src/main/res/anim/activity_close_exit.xml b/app/src/main/res/anim/activity_close_exit.xml new file mode 100644 index 000000000..feb59397d --- /dev/null +++ b/app/src/main/res/anim/activity_close_exit.xml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/app/src/main/res/anim/activity_open_enter.xml b/app/src/main/res/anim/activity_open_enter.xml new file mode 100644 index 000000000..f2bd3cc94 --- /dev/null +++ b/app/src/main/res/anim/activity_open_enter.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/app/src/main/res/anim/activity_open_exit.xml b/app/src/main/res/anim/activity_open_exit.xml new file mode 100644 index 000000000..2c08910bf --- /dev/null +++ b/app/src/main/res/anim/activity_open_exit.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/app/src/main/res/anim/fast_out_extra_slow_in.xml b/app/src/main/res/anim/fast_out_extra_slow_in.xml new file mode 100644 index 000000000..f419778d0 --- /dev/null +++ b/app/src/main/res/anim/fast_out_extra_slow_in.xml @@ -0,0 +1,18 @@ + + + diff --git a/app/src/main/res/anim/slide_from_left.xml b/app/src/main/res/anim/slide_from_left.xml deleted file mode 100644 index 5c7fe5227..000000000 --- a/app/src/main/res/anim/slide_from_left.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/anim/slide_from_right.xml b/app/src/main/res/anim/slide_from_right.xml deleted file mode 100644 index 3c595d04b..000000000 --- a/app/src/main/res/anim/slide_from_right.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/anim/slide_to_left.xml b/app/src/main/res/anim/slide_to_left.xml deleted file mode 100644 index 21688e2ca..000000000 --- a/app/src/main/res/anim/slide_to_left.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/anim/slide_to_right.xml b/app/src/main/res/anim/slide_to_right.xml deleted file mode 100644 index 8ded764f7..000000000 --- a/app/src/main/res/anim/slide_to_right.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file