Skip to content

Instantly share code, notes, and snippets.

View benigumocom's full-sized avatar
🏠
🙆

chanzmao benigumocom

🏠
🙆
View GitHub Profile
@benigumocom
benigumocom / A-NavDisplay-ActivityScopedViewModel.kt
Last active May 1, 2026 07:20
【Jetpack Compose Navigation3】EntryDecorator と ViewModel の「key」の深い関係 https://android.benigumo.com/20260501/entrydecorator-viewmodel-key/
NavDisplay(
backStack = backStack,
modifier = Modifier.padding(innerPadding),
onBack = { backStack.removeLastOrNull() },
// entryDecorators = listOf( // *
// rememberSaveableStateHolderNavEntryDecorator()
// ),
entryProvider = entryProvider {
entry<Search> { key ->
SearchScreen(
@benigumocom
benigumocom / install.sh
Created April 23, 2026 19:52
Agent tools and resources  |  Android Studio  |  Android Developers https://developer.android.com/tools/agents
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e
# === Configuration ===
BINARY_NAME="android"
INSTALL_DIR="/usr/local/bin"
OS="$(uname -s)"
@benigumocom
benigumocom / Navigation3+BottomNavigation.kt
Last active April 4, 2026 14:41
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")