Add backwards compatible implementation of overrideActivityTransition() (#4408)

This pull request adds `overrideActivityTransitionCompat()`, a
backwards-compatible version of `Activity.overrideActivityTransition()`
to be called in `Activity.onCreate()` in all Android versions.

This avoids duplicating the transition logic in different places of the
app to support older Android versions (in the activity launching code,
in `Activity.onCreate()` or in `Activity.finish()`).

- On API 34+, the implementation simply delegates to
`Activity.overrideActivityTransition()`.
- On API < 34, the implementation calls
`Activity.overridePendingTransition()` either immediately (opening
transition) or schedules it to be called later when the Activity is
finishing (closing transition).
- Rename `ActivityExensions.kt` to `ActivityExtensions.kt` (fix typo).
This commit is contained in:
Christophe Beyls 2024-05-10 13:59:35 +02:00 committed by GitHub
parent 0028ab79c3
commit d1518956e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 72 additions and 50 deletions

View File

@ -45,6 +45,7 @@ import com.keylesspalace.tusky.di.Injectable;
import com.keylesspalace.tusky.interfaces.AccountSelectionListener;
import com.keylesspalace.tusky.settings.AppTheme;
import com.keylesspalace.tusky.settings.PrefKeys;
import com.keylesspalace.tusky.util.ActivityConstants;
import com.keylesspalace.tusky.util.ActivityExtensions;
import com.keylesspalace.tusky.util.ThemeUtils;
@ -53,7 +54,6 @@ 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 {
@ -69,9 +69,19 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (supportsOverridingActivityTransitions() && activityTransitionWasRequested()) {
overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, R.anim.activity_open_enter, R.anim.activity_open_exit);
overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, R.anim.activity_close_enter, R.anim.activity_close_exit);
if (activityTransitionWasRequested()) {
ActivityExtensions.overrideActivityTransitionCompat(
this,
ActivityConstants.OVERRIDE_TRANSITION_OPEN,
R.anim.activity_open_enter,
R.anim.activity_open_exit
);
ActivityExtensions.overrideActivityTransitionCompat(
this,
ActivityConstants.OVERRIDE_TRANSITION_CLOSE,
R.anim.activity_close_enter,
R.anim.activity_close_exit
);
}
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
@ -178,15 +188,6 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
return super.onOptionsItemSelected(item);
}
@Override
public void finish() {
super.finish();
// if this activity was opened with slide-in, close it with slide out
if (!supportsOverridingActivityTransitions() && activityTransitionWasRequested()) {
overridePendingTransition(R.anim.activity_close_enter, R.anim.activity_close_exit);
}
}
protected void redirectIfNotLoggedIn() {
AccountEntity account = accountManager.getActiveAccount();
if (account == null) {

View File

@ -102,16 +102,17 @@ import com.keylesspalace.tusky.pager.MainPagerAdapter
import com.keylesspalace.tusky.settings.PrefKeys
import com.keylesspalace.tusky.usecase.DeveloperToolsUseCase
import com.keylesspalace.tusky.usecase.LogoutUsecase
import com.keylesspalace.tusky.util.ActivityConstants
import com.keylesspalace.tusky.util.ShareShortcutHelper
import com.keylesspalace.tusky.util.deleteStaleCachedMedia
import com.keylesspalace.tusky.util.emojify
import com.keylesspalace.tusky.util.getDimension
import com.keylesspalace.tusky.util.getParcelableExtraCompat
import com.keylesspalace.tusky.util.hide
import com.keylesspalace.tusky.util.overrideActivityTransitionCompat
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.viewBinding
import com.mikepenz.iconics.IconicsDrawable
@ -216,8 +217,12 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
val activeAccount = accountManager.activeAccount
?: return // will be redirected to LoginActivity by BaseActivity
if (supportsOverridingActivityTransitions() && explodeAnimationWasRequested()) {
overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, R.anim.explode, R.anim.activity_open_exit)
if (explodeAnimationWasRequested()) {
overrideActivityTransitionCompat(
ActivityConstants.OVERRIDE_TRANSITION_OPEN,
R.anim.explode,
R.anim.activity_open_exit
)
}
var showNotificationTab = false
@ -988,10 +993,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
}
startActivity(intent)
finish()
if (!supportsOverridingActivityTransitions()) {
@Suppress("DEPRECATION")
overridePendingTransition(R.anim.explode, R.anim.activity_open_exit)
}
}
private fun logout() {

View File

@ -41,7 +41,6 @@ import com.keylesspalace.tusky.util.getNonNullString
import com.keylesspalace.tusky.util.openLinkInCustomTab
import com.keylesspalace.tusky.util.rickRoll
import com.keylesspalace.tusky.util.shouldRickRoll
import com.keylesspalace.tusky.util.supportsOverridingActivityTransitions
import com.keylesspalace.tusky.util.viewBinding
import javax.inject.Inject
import kotlinx.coroutines.launch
@ -317,10 +316,6 @@ class LoginActivity : BaseActivity(), Injectable {
intent.putExtra(MainActivity.OPEN_WITH_EXPLODE_ANIMATION, true)
startActivity(intent)
finishAffinity()
if (!supportsOverridingActivityTransitions()) {
@Suppress("DEPRECATION")
overridePendingTransition(R.anim.explode, R.anim.activity_open_exit)
}
}, { e ->
setLoading(false)
binding.domainTextInputLayout.error =

View File

@ -1,25 +0,0 @@
@file:JvmName("ActivityExtensions")
package com.keylesspalace.tusky.util
import android.app.Activity
import android.content.Intent
import android.os.Build
import com.keylesspalace.tusky.BaseActivity
import com.keylesspalace.tusky.R
fun Activity.startActivityWithSlideInAnimation(intent: Intent) {
// the new transition api needs to be called by the activity that is the result of the transition,
// so we pass a flag that BaseActivity will respect.
intent.putExtra(BaseActivity.OPEN_WITH_SLIDE_IN, true)
startActivity(intent)
if (!supportsOverridingActivityTransitions()) {
// the old api needs to be called by the activity that starts the transition
@Suppress("DEPRECATION")
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
}

View File

@ -0,0 +1,50 @@
@file:JvmName("ActivityExtensions")
package com.keylesspalace.tusky.util
import android.app.Activity
import android.content.Intent
import android.os.Build
import androidx.activity.ComponentActivity
import androidx.annotation.AnimRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.keylesspalace.tusky.BaseActivity
fun Activity.startActivityWithSlideInAnimation(intent: Intent) {
// the new transition api needs to be called by the activity that is the result of the transition,
// so we pass a flag that BaseActivity will respect.
intent.putExtra(BaseActivity.OPEN_WITH_SLIDE_IN, true)
startActivity(intent)
}
/**
* Call this method in Activity.onCreate() to configure the open or close transitions.
*/
@Suppress("DEPRECATION")
fun ComponentActivity.overrideActivityTransitionCompat(
overrideType: Int,
@AnimRes enterAnim: Int,
@AnimRes exitAnim: Int
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
overrideActivityTransition(overrideType, enterAnim, exitAnim)
} else {
if (overrideType == ActivityConstants.OVERRIDE_TRANSITION_OPEN) {
overridePendingTransition(enterAnim, exitAnim)
} else {
lifecycle.addObserver(
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_PAUSE && isFinishing) {
overridePendingTransition(enterAnim, exitAnim)
}
}
)
}
}
}
object ActivityConstants {
const val OVERRIDE_TRANSITION_OPEN = 0
const val OVERRIDE_TRANSITION_CLOSE = 1
}