Skip to content

Instantly share code, notes, and snippets.

View benigumocom's full-sized avatar
🏠
🙆

chanzmao benigumocom

🏠
🙆
View GitHub Profile
@benigumocom
benigumocom / Navigation3+BottomNavigation.kt
Last active March 24, 2026 02:55
Stop Fighting Multiple BackStacks in Jetpack Compose Navigation3 | by chanzmao | Mar, 2026 | ProAndroidDev https://medium.com/proandroiddev/stop-fighting-multiple-backstacks-in-jetpack-compose-navigation3-50f8cf063fff
package com.example.samplenavigation3
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@benigumocom
benigumocom / NavBackStacks.kt
Last active March 24, 2026 03:04
Multi-Stack Navigation: Why Your BackStacks Should Be Saveable UI State https://android.benigumo.com/20260322/multi-stack-navigation/
@Composable
fun <T : NavKey> rememberNavBackStacks(
tabRoots: List<T>
): SnapshotStateMap<T, NavBackStack<NavKey>> {
return rememberSaveable(
inputs = arrayOf(tabRoots),
saver = Saver<SnapshotStateMap<T, NavBackStack<NavKey>>, List<Pair<T, NavBackStack<NavKey>>>>(
save = { map -> map.toList() },
restore = { restored ->
mutableStateMapOf<T, NavBackStack<NavKey>>().apply {
@benigumocom
benigumocom / 3-1-NavigationState.kt
Created March 11, 2026 09:21
Migrate from Navigation 2 to Navigation 3  |  App architecture  |  Android Developers https://developer.android.com/guide/navigation/navigation-3/migration-guide?hl=en
// package com.example.project
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSerializable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
@benigumocom
benigumocom / 1-sealed-interface.kt
Last active March 4, 2026 07:46
Jetpack Compose Navigation3 - Destiination sealed interface
@Serializable
sealed interface AppDestination {
val label: String
@get:DrawableRes val iconRes: Int
}
@Serializable
data object HomeDestination : AppDestination {
override val label = "Home"; override val iconRes = R.drawable.ic_home
}
@benigumocom
benigumocom / 1-nested_sealed_interface.kt
Last active March 4, 2026 07:45
Jetpack Compose Navigation3 - Destiination Nested sealed interface
@Serializable
sealed interface AppDestination {
val label: String
@get:DrawableRes val iconRes: Int
@Serializable
data object Home : AppDestination {
override val label = "Home"
override val iconRes = R.drawable.ic_home
}
// ==========================================================
// 【DEFINITION AREA】
// Must be defined at the TOP-LEVEL (Outside of any @Composable)
// ==========================================================
// A. object: A global, immutable box (Constants)
object AppDesignConfig {
val BrandColor = Color(0xFF6200EE) // Fixed brand color
val CornerRadius = 12.dp
}
@Composable
fun AnalyticsScreen(screenName: String) {
var startTime by remember { mutableLongStateOf(0L) }
ScreenLifecycleObserver { event ->
when (event) {
Lifecycle.Event.ON_RESUME -> startTime = System.currentTimeMillis()
Lifecycle.Event.ON_PAUSE -> {
val duration = System.currentTimeMillis() - startTime
Analytics.sendScreenTime(screenName, duration)
@benigumocom
benigumocom / 1-UiOnly.kt
Last active February 28, 2026 23:15
How to handle UI interactions with event processing
// No ViewModel
@Composable
fun UiOnlySample() {
val context = LocalContext.current
Button(onClick = {
Toast.makeText(context, "Clicked!", Toast.LENGTH_SHORT).show()
}) {
Text("Click")
private val Context.density: Float
get() = resources.displayMetrics.density
private val Context.scale: Float
get() = resources.displayMetrics.scaledDensity
/* ----- dp(Dp) → px(Float) ----- */
fun Context.dpToPx(dp: Dp): Float =
dp.value * density
object TestEnvironmentChecker {
/**
* Firebase Test Lab またはテスト環境で実行されているかを推定
*/
fun isRunningInTestLab(context: Context): Boolean {
return when {
isFirebaseTestLab(context) -> {
Log.d("EnvCheck", "Detected: Firebase Test Lab via system setting")
true