From 80d4d66fb53b7b6a0b40bf2d07e727b86fa436e4 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Wed, 25 Oct 2023 21:59:10 +0800 Subject: [PATCH] Dispatch insets from compose to android view --- .../com/hippo/ehviewer/ui/MainActivity.kt | 36 ++++++++++++++----- .../hippo/ehviewer/util/WindowInsetsUtil.kt | 32 +++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 app/src/main/kotlin/com/hippo/ehviewer/util/WindowInsetsUtil.kt diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/MainActivity.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/MainActivity.kt index 5eaa28d18..77197e718 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/MainActivity.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/MainActivity.kt @@ -33,8 +33,10 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.DrawerValue @@ -56,6 +58,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidViewBinding import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment @@ -81,8 +86,10 @@ import com.hippo.ehviewer.ui.scene.navAnimated import com.hippo.ehviewer.ui.scene.navWithUrl import com.hippo.ehviewer.util.AppConfig import com.hippo.ehviewer.util.addTextToClipboard +import com.hippo.ehviewer.util.buildWindowInsets import com.hippo.ehviewer.util.getParcelableExtraCompat import com.hippo.ehviewer.util.getUrlFromClipboard +import com.hippo.ehviewer.util.set import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.withUIContext import java.io.File @@ -194,8 +201,7 @@ class MainActivity : EhActivity() { override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) - // Disable this until insets are correctly handled - // WindowCompat.setDecorFitsSystemWindows(window, false) + WindowCompat.setDecorFitsSystemWindows(window, false) setMD3Content { val drawerState = rememberDrawerState(DrawerValue.Closed) val scope = rememberCoroutineScope() @@ -247,14 +253,28 @@ class MainActivity : EhActivity() { // Disabled for breaking custom swipe gestures gesturesEnabled = drawerState.isOpen, ) { - AndroidViewBinding(factory = ActivityMainBinding::inflate) { - val navHostFragment = fragmentContainer.getFragment() - navController = navHostFragment.navController.apply { - graph = navInflater.inflate(R.navigation.nav_graph).apply { - check(launchPage in 0..3) - setStartDestination(navItems[launchPage].first) + val insets = buildWindowInsets { + set( + WindowInsetsCompat.Type.systemBars(), + WindowInsets.systemBars, + ) + set( + WindowInsetsCompat.Type.ime(), + WindowInsets.ime, + ) + } + AndroidViewBinding(factory = { inflater, parent, attachToParent -> + ActivityMainBinding.inflate(inflater, parent, attachToParent).apply { + val navHostFragment = fragmentContainer.getFragment() + navController = navHostFragment.navController.apply { + graph = navInflater.inflate(R.navigation.nav_graph).apply { + check(launchPage in 0..3) + setStartDestination(navItems[launchPage].first) + } } } + }) { + ViewCompat.dispatchApplyWindowInsets(root, insets) } } } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/WindowInsetsUtil.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/WindowInsetsUtil.kt new file mode 100644 index 000000000..8636875a0 --- /dev/null +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/WindowInsetsUtil.kt @@ -0,0 +1,32 @@ +package com.hippo.ehviewer.util + +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.core.graphics.Insets +import androidx.core.view.WindowInsetsCompat +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +inline fun buildWindowInsets(builderAction: WindowInsetsCompat.Builder.() -> Unit): WindowInsetsCompat { + contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } + val builder = WindowInsetsCompat.Builder() + builder.builderAction() + return builder.build() +} + +@Composable +fun WindowInsetsCompat.Builder.set(type: Int, insets: WindowInsets): WindowInsetsCompat.Builder { + val density = LocalDensity.current + val layoutDirection = LocalLayoutDirection.current + return setInsets( + type, + Insets.of( + insets.getLeft(density, layoutDirection), + insets.getTop(density), + insets.getRight(density, layoutDirection), + insets.getBottom(density), + ), + ) +}