跳到正文
cccskills
免费在 GitHub 公开

jetpack-compose-navigation-expert

Jetpack Compose navigation expert with type-safe routes, Hilt DI, and MVVM/MVI architecture. Activate on: Jetpack Compose navigation, Compose type-safe routes, Hilt dependency injection, MVVM Android, MVI pattern, Compose state management, NavHost, ViewModel. NOT for: XML layouts (use frontend-architect), iOS SwiftUI (use swiftui-data-flow-expert), React Native (use react-native-architect).

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md6.9 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Jetpack Compose Navigation Expert

Expert in Jetpack Compose navigation with type-safe routes, Hilt dependency injection, and clean MVVM/MVI architecture.

Activation Triggers

Activate on: "Jetpack Compose navigation", "Compose type-safe routes", "Hilt DI", "MVVM Android", "MVI pattern", "Compose state management", "NavHost", "ViewModel Compose", "navigation-compose"

NOT for: XML layouts → frontend-architect | iOS SwiftUI → swiftui-data-flow-expert | React Native → react-native-architect

Quick Start

  1. Add Navigation Compose — implementation("androidx.navigation:navigation-compose:2.9.x") with type-safe routes
  2. Define routes as serializable classes — @Serializable data class ProductRoute(val id: String)
  3. Set up Hilt — @HiltViewModel for ViewModels with constructor injection
  4. Implement MVVM — ViewModel holds UI state, composables observe via collectAsStateWithLifecycle
  5. Handle deep links — declarative deep link mapping in NavHost

Core Capabilities

DomainTechnologies
NavigationNavigation Compose 2.9, type-safe routes, nested graphs
DIHilt 2.53, @HiltViewModel, @Inject, module scoping
ArchitectureMVVM, MVI (Circuit, Mavericks), UDF (unidirectional data flow)
StateStateFlow, collectAsStateWithLifecycle, SavedStateHandle
AsyncKotlin Coroutines, Flow, Room with Flow, Retrofit suspend

Architecture Patterns

Type-Safe Navigation (Compose 2.8+)

// Define routes as serializable data classes
@Serializable
data object HomeRoute

@Serializable
data class ProductRoute(val productId: String)

@Serializable
data class OrderRoute(val orderId: String, val showConfirmation: Boolean = false)

// NavHost with type-safe composable destinations
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
    NavHost(navController = navController, startDestination = HomeRoute) {
        composable<HomeRoute> {
            HomeScreen(
                onProductClick = { id ->
                    navController.navigate(ProductRoute(productId = id))
                }
            )
        }
        composable<ProductRoute> { backStackEntry ->
            val route = backStackEntry.toRoute<ProductRoute>()
            ProductScreen(productId = route.productId)
        }
        composable<OrderRoute> { backStackEntry ->
            val route = backStackEntry.toRoute<OrderRoute>()
            OrderScreen(orderId = route.orderId)
        }
    }
}

MVVM with Hilt and UDF

@HiltViewModel
class ProductViewModel @Inject constructor(
    private val repository: ProductRepository,
    savedStateHandle: SavedStateHandle,
) : ViewModel() {

    private val productId: String = savedStateHandle.toRoute<ProductRoute>().productId

    private val _uiState = MutableStateFlow<ProductUiState>(ProductUiState.Loading)
    val uiState: StateFlow<ProductUiState> = _uiState.asStateFlow()

    init { loadProduct() }

    fun onEvent(event: ProductEvent) {
        when (event) {
            is ProductEvent.AddToCart -> addToCart(event.quantity)
            is ProductEvent.Refresh -> loadProduct()
        }
    }

    private fun loadProduct() {
        viewModelScope.launch {
            _uiState.value = ProductUiState.Loading
            repository.getProduct(productId)
                .onSuccess { _uiState.value = ProductUiState.Success(it) }
                .onFailure { _uiState.value = ProductUiState.Error(it.message) }
        }
    }
}

// Composable observes state
@Composable
fun ProductScreen(viewModel: ProductViewModel = hiltViewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    when (val state = uiState) {
        is ProductUiState.Loading -> LoadingIndicator()
        is ProductUiState.Success -> ProductContent(
            product = state.product,
            onEvent = viewModel::onEvent,
        )
        is ProductUiState.Error -> ErrorMessage(state.message)
    }
}

Nested Navigation Graphs

Root NavHost
  ├─ Auth Graph (unauthenticated)
  │   ├─ Login
  │   ├─ Register
  │   └─ ForgotPassword
  ├─ Main Graph (authenticated)
  │   ├─ Home Tab
  │   │   ├─ Feed
  │   │   └─ Product Detail
  │   ├─ Search Tab
  │   │   ├─ Search
  │   │   └─ Category
  │   └─ Profile Tab
  │       ├─ Profile
  │       └─ Settings
  └─ Fullscreen overlays (shared)
      ├─ ImageViewer
      └─ VideoPlayer

Anti-Patterns

  1. String-based routes — navController.navigate("product/123") is error-prone. Use type-safe route classes (@Serializable data class ProductRoute(val id: String)).
  2. ViewModel in composable — creating ViewModel instances inside composables. Use hiltViewModel() which handles scoping to the NavBackStackEntry.
  3. Collecting Flow without lifecycle — collectAsState() keeps collecting when the app is backgrounded. Use collectAsStateWithLifecycle() to respect lifecycle.
  4. God ViewModel — single ViewModel for an entire feature with 20+ state fields. Split into smaller ViewModels or use MVI with sealed state classes.
  5. Navigation in ViewModel — calling navController.navigate() from ViewModel. Instead, expose navigation events via SharedFlow or callback lambdas; let the composable handle navigation.

Quality Checklist

[ ] Type-safe navigation routes using @Serializable classes
[ ] Hilt configured with @HiltViewModel for all ViewModels
[ ] UI state collected with collectAsStateWithLifecycle
[ ] Unidirectional data flow: events up, state down
[ ] Deep links configured in NavHost
[ ] Navigation tested with TestNavHostController
[ ] SavedStateHandle used for process death restoration
[ ] Nested graphs for auth, main, and feature flows
[ ] No navigation logic in ViewModels (events/callbacks instead)
[ ] Compose previews with mock data for all screens
[ ] ProGuard/R8 rules configured for serializable routes
[ ] Screen transitions animated with shared element transitions

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Expert in 2000s-era music visualization (Milkdrop, AVS, Geiss) and modern WebGL implementations. Specializes in Butterchurn integration, Web Audio API AnalyserNode FFT data, GLSL shaders for audio-reactive visuals, and psychedelic generative art. Activate on "Milkdrop", "music visualization", "WebGL visualizer", "Butterchurn", "audio reactive", "FFT visualization", "spectrum analyzer". NOT for simple bar charts/waveforms (use basic canvas), video editing, or non-audio visuals.

中文简介正在准备中。当前显示原文说明。

curiositech/windags-skills162026年10月19日 更新

Expert legal research agent for finding and scraping expungement data state by state. Knows authoritative sources, URL patterns, Firecrawl configuration, and 2026 legal landscape.

中文简介正在准备中。当前显示原文说明。

curiositech/windags-skills162026年10月19日 更新

Expert in 3D computer vision labeling tools, workflows, and AI-assisted annotation for LiDAR, point clouds, and sensor fusion. Covers SAM4D/Point-SAM, human-in-the-loop architectures, and vertical-specific training strategies. Activate on '3D labeling', 'point cloud annotation', 'LiDAR labeling', 'SAM 3D', 'SAM4D', 'sensor fusion annotation', '3D bounding box', 'semantic segmentation point cloud'. NOT for 2D image labeling (use clip-aware-embeddings), general ML training (use ml-engineer), video annotation without 3D (use computer-vision-pipeline), or VLM prompt engineering (use prompt-engineer).

中文简介正在准备中。当前显示原文说明。

curiositech/windags-skills162026年10月19日 更新

Apply crisis decision-making research to agent routing, uncertainty triage, and coordination failure analysis in time-pressured systems. Use when diagnosing handoff failures, analytical paralysis, or expert judgment under incomplete information. NOT for routine coding, simple CRUD design, or static single-agent tasks with complete information.

中文简介正在准备中。当前显示原文说明。

curiositech/windags-skills162026年10月19日 更新

Use for insight, reframing, contradiction, impasse, and anomaly-driven problem solving when execution effort no longer helps. NOT for routine optimization, error correction, or well-specified tasks with known solution paths.

中文简介正在准备中。当前显示原文说明。

curiositech/windags-skills162026年10月19日 更新

Apply normative BDI reasoning to agents that must detect norms, choose which commitments to internalize, and resolve conflicts by comparing consequences. Use when obligations, prohibitions, or policies collide in autonomous systems. NOT for simple fixed-priority rules, pure constraint satisfaction, or domains where no real normative conflict exists.

中文简介正在准备中。当前显示原文说明。

curiositech/windags-skills162026年10月19日 更新

查看 curiositech 的全部技能

报告此技能的问题