feat(characters): Koin module + nav graph + wire into :app (REDI-89)
- charactersPresentationModule: viewModelOf(::CharacterListViewModel) (in the UI-agnostic module).
- @Serializable CharacterListRoute + NavGraphBuilder.charactersGraph { composable<CharacterListRoute> }
in presentation-compose (serialization plugin added for type-safe routes).
- :app registers coreDataModule + charactersDataModule + charactersPresentationModule in startKoin,
and hosts a NavHost(startDestination = CharacterListRoute) calling charactersGraph.
- core:data manifest declares INTERNET (merges into :app) for live API calls.
This commit is contained in:
@@ -2,14 +2,16 @@ package com.example.architecture
|
||||
|
||||
import android.app.Application
|
||||
import com.example.architecture.core.data.di.coreDataModule
|
||||
import com.example.architecture.feature.characters.data.di.charactersDataModule
|
||||
import com.example.architecture.feature.characters.presentation.di.charactersPresentationModule
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
import org.koin.core.context.startKoin
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Single Koin entry point. Feature modules append their own `*DataModule` / `*PresentationModule`
|
||||
* to the [modules] list — assembly happens only here, never inside feature modules.
|
||||
* Single Koin entry point. Every feature's `*DataModule` / `*PresentationModule` is assembled here,
|
||||
* never inside feature modules.
|
||||
*/
|
||||
class ArchitectureApp : Application() {
|
||||
override fun onCreate() {
|
||||
@@ -24,7 +26,11 @@ class ArchitectureApp : Application() {
|
||||
androidLogger()
|
||||
androidContext(this@ArchitectureApp)
|
||||
modules(
|
||||
// core
|
||||
coreDataModule,
|
||||
// characters feature
|
||||
charactersDataModule,
|
||||
charactersPresentationModule,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,31 +4,26 @@ import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.example.architecture.core.design.system.component.AppScaffold
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.example.architecture.core.design.system.theme.AppTheme
|
||||
import com.example.architecture.feature.characters.presentation.compose.CharacterListRoute
|
||||
import com.example.architecture.feature.characters.presentation.compose.charactersGraph
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
// Compose themes via AppTheme; the navigation host lands in a later milestone.
|
||||
AppTheme {
|
||||
AppScaffold { innerPadding ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(text = "Android Architecture Showcase")
|
||||
}
|
||||
val navController = rememberNavController()
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = CharacterListRoute,
|
||||
) {
|
||||
charactersGraph(
|
||||
onCharacterClick = { /* Detail navigation is wired in the next milestone. */ },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user