pref(MainActivity): 优化主页面性能 (#209)
Reduce unnecessary recomposition, removed unnecessary "remember", and merged Background and Surface components.
This commit is contained in:
parent
6527155925
commit
2b3dd20f65
|
|
@ -19,7 +19,6 @@ import androidx.compose.animation.core.AnimationSpec
|
||||||
import androidx.compose.animation.core.Spring
|
import androidx.compose.animation.core.Spring
|
||||||
import androidx.compose.animation.core.VisibilityThreshold
|
import androidx.compose.animation.core.VisibilityThreshold
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
|
@ -49,7 +48,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
import androidx.lifecycle.flowWithLifecycle
|
import androidx.lifecycle.flowWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.navigation.plusAssign
|
import androidx.navigation.plusAssign
|
||||||
import androidx.window.layout.FoldingFeature
|
import androidx.window.layout.FoldingFeature
|
||||||
|
|
@ -114,7 +113,7 @@ val LocalNotificationCountFlow =
|
||||||
val LocalDevicePosture =
|
val LocalDevicePosture =
|
||||||
staticCompositionLocalOf<State<DevicePosture>> { throw IllegalStateException("not allowed here!") }
|
staticCompositionLocalOf<State<DevicePosture>> { throw IllegalStateException("not allowed here!") }
|
||||||
val LocalNavController =
|
val LocalNavController =
|
||||||
staticCompositionLocalOf<NavController> { throw IllegalStateException("not allowed here!") }
|
staticCompositionLocalOf<NavHostController> { throw IllegalStateException("not allowed here!") }
|
||||||
val LocalDestination = compositionLocalOf<DestinationSpec<*>?> { null }
|
val LocalDestination = compositionLocalOf<DestinationSpec<*>?> { null }
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialNavigationApi::class)
|
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialNavigationApi::class)
|
||||||
|
|
@ -276,94 +275,44 @@ class MainActivityV2 : BaseComposeActivity() {
|
||||||
PickMediasRequest(it.id, it.maxCount, it.mediaType)
|
PickMediasRequest(it.id, it.maxCount, it.mediaType)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CompositionLocalProvider(
|
TiebaLiteLocalProvider {
|
||||||
LocalNotificationCountFlow provides notificationCountFlow,
|
TranslucentThemeBackground {
|
||||||
LocalDevicePosture provides devicePostureFlow.collectAsState(),
|
val navController = rememberNavController()
|
||||||
) {
|
val engine = TiebaNavHostDefaults.rememberNavHostEngine()
|
||||||
Box {
|
val navigator = TiebaNavHostDefaults.rememberBottomSheetNavigator()
|
||||||
TranslucentThemeBackground()
|
val currentDestination by navController.currentDestinationAsState()
|
||||||
|
|
||||||
Surface(
|
navController.navigatorProvider += navigator
|
||||||
color = ExtendedTheme.colors.background
|
|
||||||
|
LaunchedEffect(currentDestination) {
|
||||||
|
val curDest = currentDestination
|
||||||
|
if (curDest != null) {
|
||||||
|
Analytics.trackEvent(
|
||||||
|
"PageChanged",
|
||||||
|
mapOf(
|
||||||
|
"page" to curDest.route,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalNavController provides navController,
|
||||||
|
LocalDestination provides currentDestination,
|
||||||
) {
|
) {
|
||||||
val animationSpec = remember {
|
ModalBottomSheetLayout(
|
||||||
spring(
|
bottomSheetNavigator = navigator,
|
||||||
stiffness = Spring.StiffnessMediumLow,
|
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
|
||||||
visibilityThreshold = IntOffset.VisibilityThreshold
|
sheetBackgroundColor = ExtendedTheme.colors.windowBackground
|
||||||
)
|
|
||||||
}
|
|
||||||
val engine = rememberAnimatedNavHostEngine(
|
|
||||||
navHostContentAlignment = Alignment.TopStart,
|
|
||||||
rootDefaultAnimations = RootNavGraphDefaultAnimations(
|
|
||||||
enterTransition = {
|
|
||||||
slideIntoContainer(
|
|
||||||
AnimatedContentTransitionScope.SlideDirection.Start,
|
|
||||||
animationSpec = animationSpec,
|
|
||||||
initialOffset = { it }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
exitTransition = {
|
|
||||||
slideOutOfContainer(
|
|
||||||
AnimatedContentTransitionScope.SlideDirection.End,
|
|
||||||
animationSpec = animationSpec,
|
|
||||||
targetOffset = { -it }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
popEnterTransition = {
|
|
||||||
slideIntoContainer(
|
|
||||||
AnimatedContentTransitionScope.SlideDirection.Start,
|
|
||||||
animationSpec = animationSpec,
|
|
||||||
initialOffset = { -it }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
popExitTransition = {
|
|
||||||
slideOutOfContainer(
|
|
||||||
AnimatedContentTransitionScope.SlideDirection.End,
|
|
||||||
animationSpec = animationSpec,
|
|
||||||
targetOffset = { it }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
val navController = rememberNavController()
|
|
||||||
val bottomSheetNavigator =
|
|
||||||
rememberBottomSheetNavigator(
|
|
||||||
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
|
||||||
skipHalfExpanded = true
|
|
||||||
)
|
|
||||||
navController.navigatorProvider += bottomSheetNavigator
|
|
||||||
|
|
||||||
val currentDestination by navController.currentDestinationAsState()
|
|
||||||
LaunchedEffect(currentDestination) {
|
|
||||||
val curDest = currentDestination
|
|
||||||
if (curDest != null) {
|
|
||||||
Analytics.trackEvent(
|
|
||||||
"PageChanged",
|
|
||||||
mapOf(
|
|
||||||
"page" to curDest.route,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalNavController provides navController,
|
|
||||||
LocalDestination provides currentDestination
|
|
||||||
) {
|
) {
|
||||||
ModalBottomSheetLayout(
|
DestinationsNavHost(
|
||||||
bottomSheetNavigator = bottomSheetNavigator,
|
navController = navController,
|
||||||
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
|
navGraph = NavGraphs.root,
|
||||||
sheetBackgroundColor = ExtendedTheme.colors.windowBackground,
|
engine = engine,
|
||||||
) {
|
dependenciesContainerBuilder = {
|
||||||
DestinationsNavHost(
|
dependency(MainPageDestination) { this@MainActivityV2 }
|
||||||
navController = navController,
|
}
|
||||||
navGraph = NavGraphs.root,
|
)
|
||||||
engine = engine,
|
|
||||||
dependenciesContainerBuilder = {
|
|
||||||
dependency(MainPageDestination) { this@MainActivityV2 }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -371,19 +320,38 @@ class MainActivityV2 : BaseComposeActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TranslucentThemeBackground() {
|
private fun TranslucentThemeBackground(
|
||||||
if (ThemeUtil.isTranslucentTheme(ExtendedTheme.colors.theme)) {
|
modifier: Modifier = Modifier,
|
||||||
val backgroundPath by rememberPreferenceAsMutableState(
|
content: @Composable () -> Unit,
|
||||||
key = stringPreferencesKey("translucent_theme_background_path"),
|
) {
|
||||||
defaultValue = ""
|
Surface(
|
||||||
)
|
color = ExtendedTheme.colors.background,
|
||||||
val backgroundUri by remember { derivedStateOf { newFileUri(backgroundPath) } }
|
modifier = modifier
|
||||||
AsyncImage(
|
) {
|
||||||
imageUri = backgroundUri,
|
if (ThemeUtil.isTranslucentTheme(ExtendedTheme.colors.theme)) {
|
||||||
contentDescription = null,
|
val backgroundPath by rememberPreferenceAsMutableState(
|
||||||
modifier = Modifier.fillMaxSize(),
|
key = stringPreferencesKey("translucent_theme_background_path"),
|
||||||
contentScale = ContentScale.Crop
|
defaultValue = ""
|
||||||
)
|
)
|
||||||
|
val backgroundUri by remember { derivedStateOf { newFileUri(backgroundPath) } }
|
||||||
|
AsyncImage(
|
||||||
|
imageUri = backgroundUri,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
}
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TiebaLiteLocalProvider(content: @Composable () -> Unit) {
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalNotificationCountFlow provides notificationCountFlow,
|
||||||
|
LocalDevicePosture provides devicePostureFlow.collectAsState(),
|
||||||
|
) {
|
||||||
|
content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -401,4 +369,54 @@ class MainActivityV2 : BaseComposeActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object TiebaNavHostDefaults {
|
||||||
|
private val AnimationSpec = spring(
|
||||||
|
stiffness = Spring.StiffnessMediumLow,
|
||||||
|
visibilityThreshold = IntOffset.VisibilityThreshold
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalMaterialNavigationApi::class, ExperimentalAnimationApi::class)
|
||||||
|
fun rememberNavHostEngine() = rememberAnimatedNavHostEngine(
|
||||||
|
navHostContentAlignment = Alignment.TopStart,
|
||||||
|
rootDefaultAnimations = RootNavGraphDefaultAnimations(
|
||||||
|
enterTransition = {
|
||||||
|
slideIntoContainer(
|
||||||
|
AnimatedContentTransitionScope.SlideDirection.Start,
|
||||||
|
animationSpec = AnimationSpec,
|
||||||
|
initialOffset = { it }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
exitTransition = {
|
||||||
|
slideOutOfContainer(
|
||||||
|
AnimatedContentTransitionScope.SlideDirection.End,
|
||||||
|
animationSpec = AnimationSpec,
|
||||||
|
targetOffset = { -it }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
popEnterTransition = {
|
||||||
|
slideIntoContainer(
|
||||||
|
AnimatedContentTransitionScope.SlideDirection.Start,
|
||||||
|
animationSpec = AnimationSpec,
|
||||||
|
initialOffset = { -it }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
popExitTransition = {
|
||||||
|
slideOutOfContainer(
|
||||||
|
AnimatedContentTransitionScope.SlideDirection.End,
|
||||||
|
animationSpec = AnimationSpec,
|
||||||
|
targetOffset = { it }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialNavigationApi::class)
|
||||||
|
@Composable
|
||||||
|
fun rememberBottomSheetNavigator(): BottomSheetNavigator = rememberBottomSheetNavigator(
|
||||||
|
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
||||||
|
skipHalfExpanded = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ buildscript {
|
||||||
booster_version = '4.16.2'
|
booster_version = '4.16.2'
|
||||||
lottie_version = '6.1.0'
|
lottie_version = '6.1.0'
|
||||||
debug = gradle.startParameter.taskNames.any {
|
debug = gradle.startParameter.taskNames.any {
|
||||||
it.contains('debug') || it.contains('Debug')
|
it.containsIgnoreCase('debug')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue