Skip to content

Commit

Permalink
Adjust screen transitions (#8707)
Browse files Browse the repository at this point in the history
* Fade transition between main navigation tabs
* Shared axis X between screen stacks

Activity transition is using a "close enough" shared axis X xml animation
  • Loading branch information
ivaniskandar committed Dec 9, 2022
1 parent d97eab0 commit 82a3a98
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 62 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ dependencies {
implementation(libs.cascade)
implementation(libs.bundles.voyager)
implementation(libs.wheelpicker)
implementation(libs.materialmotion.core)

// Logging
implementation(libs.logcat)
Expand Down
17 changes: 0 additions & 17 deletions app/src/main/java/eu/kanade/presentation/util/Constants.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package eu.kanade.presentation.util

import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.with
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.unit.dp
Expand All @@ -29,15 +24,3 @@ class Padding {

val MaterialTheme.padding: Padding
get() = Padding()

object Transition {

/**
* Mimics [eu.kanade.tachiyomi.ui.base.controller.OneWayFadeChangeHandler]
*/
val OneWayFade = fadeIn(
animationSpec = tween(
easing = LinearEasing,
),
) with ExitTransition.None
}
19 changes: 19 additions & 0 deletions app/src/main/java/eu/kanade/presentation/util/Navigator.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package eu.kanade.presentation.util

import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.staticCompositionLocalOf
import cafe.adriel.voyager.core.stack.StackEvent
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.transitions.ScreenTransition
import soup.compose.material.motion.animation.materialSharedAxisX
import soup.compose.material.motion.animation.rememberSlideDistance

/**
* For invoking back press to the parent activity
Expand All @@ -12,3 +17,17 @@ val LocalBackPress: ProvidableCompositionLocal<(() -> Unit)?> = staticCompositio
interface Tab : cafe.adriel.voyager.navigator.tab.Tab {
suspend fun onReselect(navigator: Navigator) {}
}

@Composable
fun DefaultNavigatorScreenTransition(navigator: Navigator) {
val slideDistance = rememberSlideDistance()
ScreenTransition(
navigator = navigator,
transition = {
materialSharedAxisX(
forward = navigator.lastEvent != StackEvent.Pop,
slideDistance = slideDistance,
)
},
)
}
11 changes: 9 additions & 2 deletions app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.with
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
Expand Down Expand Up @@ -41,7 +42,6 @@ import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.components.NavigationBar
import eu.kanade.presentation.components.NavigationRail
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.util.Transition
import eu.kanade.presentation.util.isTabletUi
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.BrowseTab
Expand All @@ -55,6 +55,8 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import soup.compose.material.motion.animation.materialFadeThroughIn
import soup.compose.material.motion.animation.materialFadeThroughOut
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

Expand All @@ -64,6 +66,8 @@ object HomeScreen : Screen {
private val openTabEvent = Channel<Tab>()
private val showBottomNavEvent = Channel<Boolean>()

private const val TabFadeDuration = 200

private val tabs = listOf(
LibraryTab,
UpdatesTab,
Expand Down Expand Up @@ -116,7 +120,10 @@ object HomeScreen : Screen {
) {
AnimatedContent(
targetState = tabNavigator.current,
transitionSpec = { Transition.OneWayFade },
transitionSpec = {
materialFadeThroughIn(initialScale = 1f, durationMillis = TabFadeDuration) with
materialFadeThroughOut(durationMillis = TabFadeDuration)
},
content = {
tabNavigator.saveableState(key = "currentTab", it) {
it.Content()
Expand Down
12 changes: 2 additions & 10 deletions app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.Window
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.isSystemInDarkTheme
Expand Down Expand Up @@ -42,16 +41,14 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.transitions.ScreenTransition
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.components.AppStateBanners
import eu.kanade.presentation.util.Transition
import eu.kanade.presentation.util.DefaultNavigatorScreenTransition
import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.Migrations
Expand Down Expand Up @@ -118,11 +115,6 @@ class MainActivity : BaseActivity() {
// Prevent splash screen showing up on configuration changes
val splashScreen = if (savedInstanceState == null) installSplashScreen() else null

// Set up shared element transition and disable overlay so views don't show above system bars
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementsUseOverlay = false

super.onCreate(savedInstanceState)

val didMigration = if (savedInstanceState == null) {
Expand Down Expand Up @@ -196,7 +188,7 @@ class MainActivity : BaseActivity() {
}
Box(modifier = boxModifier) {
// Shows current screen
ScreenTransition(navigator = navigator, transition = { Transition.OneWayFade })
DefaultNavigatorScreenTransition(navigator = navigator)
}

// Pop source-related screens when incognito mode is turned off
Expand Down
23 changes: 2 additions & 21 deletions app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.View.LAYER_TYPE_HARDWARE
import android.view.Window
import android.view.WindowManager
import android.view.animation.Animation
import android.view.animation.AnimationUtils
Expand All @@ -43,11 +41,9 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.slider.Slider
import com.google.android.material.transition.platform.MaterialContainerTransform
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications
Expand Down Expand Up @@ -115,9 +111,6 @@ class ReaderActivity : BaseActivity() {

private const val ENABLED_BUTTON_IMAGE_ALPHA = 255
private const val DISABLED_BUTTON_IMAGE_ALPHA = 64

const val EXTRA_IS_TRANSITION = "${BuildConfig.APPLICATION_ID}.READER_IS_TRANSITION"
const val SHARED_ELEMENT_NAME = "reader_shared_element_root"
}

private val readerPreferences: ReaderPreferences by injectLazy()
Expand Down Expand Up @@ -168,20 +161,7 @@ class ReaderActivity : BaseActivity() {
*/
override fun onCreate(savedInstanceState: Bundle?) {
registerSecureActivity(this)

// Setup shared element transitions
if (intent.extras?.getBoolean(EXTRA_IS_TRANSITION) == true) {
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
findViewById<View>(android.R.id.content)?.let { contentView ->
contentView.transitionName = SHARED_ELEMENT_NAME
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementEnterTransition = buildContainerTransform(true)
window.sharedElementReturnTransition = buildContainerTransform(false)

// Postpone custom transition until manga ready
postponeEnterTransition()
}
}
overridePendingTransition(R.anim.shared_axis_x_push_enter, R.anim.shared_axis_x_push_exit)

super.onCreate(savedInstanceState)

Expand Down Expand Up @@ -357,6 +337,7 @@ class ReaderActivity : BaseActivity() {
override fun finish() {
viewModel.onActivityFinish()
super.finish()
overridePendingTransition(R.anim.shared_axis_x_pop_enter, R.anim.shared_axis_x_pop_exit)
}

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
Expand Down
15 changes: 3 additions & 12 deletions app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.transitions.ScreenTransition
import eu.kanade.presentation.components.TwoPanelBox
import eu.kanade.presentation.more.settings.screen.AboutScreen
import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen
import eu.kanade.presentation.more.settings.screen.SettingsGeneralScreen
import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
import eu.kanade.presentation.util.DefaultNavigatorScreenTransition
import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Transition
import eu.kanade.presentation.util.isTabletUi

class SettingsScreen private constructor(
Expand Down Expand Up @@ -42,10 +41,7 @@ class SettingsScreen private constructor(
}
}
CompositionLocalProvider(LocalBackPress provides pop) {
ScreenTransition(
navigator = it,
transition = { Transition.OneWayFade },
)
DefaultNavigatorScreenTransition(navigator = it)
}
},
)
Expand All @@ -65,12 +61,7 @@ class SettingsScreen private constructor(
SettingsMainScreen.Content(twoPane = true)
}
},
endContent = {
ScreenTransition(
navigator = it,
transition = { Transition.OneWayFade },
)
},
endContent = { DefaultNavigatorScreenTransition(navigator = it) },
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class WebViewActivity : BaseActivity() {
}

override fun onCreate(savedInstanceState: Bundle?) {
overridePendingTransition(R.anim.shared_axis_x_push_enter, R.anim.shared_axis_x_push_exit)
super.onCreate(savedInstanceState)

if (!WebViewUtil.supportsWebView(this)) {
Expand Down Expand Up @@ -58,6 +59,11 @@ class WebViewActivity : BaseActivity() {
}
}

override fun finish() {
super.finish()
overridePendingTransition(R.anim.shared_axis_x_pop_enter, R.anim.shared_axis_x_pop_exit)
}

private fun shareWebpage(url: String) {
try {
startActivity(url.toUri().toShareIntent(this, type = "text/plain"))
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/res/anim-v33/shared_axis_x_pop_enter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="-30dp"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="0" />
<alpha
android:duration="195"
android:fromAlpha="0"
android:interpolator="@android:interpolator/linear_out_slow_in"
android:toAlpha="1" />
</set>
14 changes: 14 additions & 0 deletions app/src/main/res/anim-v33/shared_axis_x_pop_exit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="30dp" />

<alpha
android:duration="195"
android:fromAlpha="1"
android:interpolator="@android:interpolator/fast_out_linear_in"
android:toAlpha="0" />
</set>
13 changes: 13 additions & 0 deletions app/src/main/res/anim-v33/shared_axis_x_push_enter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="30dp"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="0" />
<alpha
android:duration="195"
android:fromAlpha="0"
android:interpolator="@android:interpolator/linear_out_slow_in"
android:toAlpha="1" />
</set>
14 changes: 14 additions & 0 deletions app/src/main/res/anim-v33/shared_axis_x_push_exit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="-30dp" />

<alpha
android:duration="195"
android:fromAlpha="1"
android:interpolator="@android:interpolator/fast_out_linear_in"
android:toAlpha="0" />
</set>
13 changes: 13 additions & 0 deletions app/src/main/res/anim/shared_axis_x_pop_enter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="-5%p"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="0" />
<alpha
android:duration="195"
android:fromAlpha="0"
android:interpolator="@android:interpolator/linear_out_slow_in"
android:toAlpha="1" />
</set>
14 changes: 14 additions & 0 deletions app/src/main/res/anim/shared_axis_x_pop_exit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="5%p" />

<alpha
android:duration="195"
android:fromAlpha="1"
android:interpolator="@android:interpolator/fast_out_linear_in"
android:toAlpha="0" />
</set>
13 changes: 13 additions & 0 deletions app/src/main/res/anim/shared_axis_x_push_enter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="5%p"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="0" />
<alpha
android:duration="195"
android:fromAlpha="0"
android:interpolator="@android:interpolator/linear_out_slow_in"
android:toAlpha="1" />
</set>
14 changes: 14 additions & 0 deletions app/src/main/res/anim/shared_axis_x_push_exit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:toXDelta="-5%p" />

<alpha
android:duration="195"
android:fromAlpha="1"
android:interpolator="@android:interpolator/fast_out_linear_in"
android:toAlpha="0" />
</set>
Loading

0 comments on commit 82a3a98

Please sign in to comment.