Skip to content

Commit

Permalink
setup di, navigation, create main screens
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrucaraus committed Jul 31, 2024
1 parent c9ffb3d commit 9d5f5e8
Show file tree
Hide file tree
Showing 14 changed files with 288 additions and 30 deletions.
20 changes: 19 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.ksp)
alias(libs.plugins.ktlint)
}

dependencies {

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)

implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.navigation)
implementation(libs.androidx.compose.navigation.common)
implementation(libs.androidx.compose.navigation.common.ktx)
implementation(libs.androidx.compose.icons.extended)
implementation(libs.androidx.material3)

implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)

implementation(platform(libs.koin.bom))
implementation(libs.koin.core)
implementation(libs.koin.android)
implementation(libs.koin.android.compose)
implementation(libs.koin.annotations)
ksp(libs.koin.ksp)

androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand Down Expand Up @@ -75,3 +89,7 @@ android {
}
}
}

ksp {
arg("KOIN_CONFIG_CHECK", "true")
}
6 changes: 3 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.NewsApp"
android:name=".main.MainApplication"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".main.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.NewsApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand All @@ -25,4 +25,4 @@
</activity>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,47 +1,28 @@
package com.germanautolabs.acaraus
package com.germanautolabs.acaraus.main

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.germanautolabs.acaraus.ui.theme.NewsAppTheme

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
render()
}

private fun render() {
enableEdgeToEdge()
setContent {
NewsAppTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding),
)
MainNavHost(innerPadding = innerPadding)
}
}
}
}
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier,
)
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
NewsAppTheme {
Greeting("Android")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.germanautolabs.acaraus.main

import android.app.Application

class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
setupMainDi(this@MainApplication)
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/com/germanautolabs/acaraus/main/MainDi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.germanautolabs.acaraus.main

import android.content.Context
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.core.context.startKoin
import org.koin.core.logger.Level
import org.koin.ksp.generated.module

@ComponentScan(value = "com.germanautolabs.acaraus")
@Module
class MainDi

fun setupMainDi(applicationContext: Context) = startKoin {
androidLogger(Level.WARNING)
androidContext(applicationContext)
modules(
MainDi().module,
)
}
35 changes: 35 additions & 0 deletions app/src/main/java/com/germanautolabs/acaraus/main/MainNavHost.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.germanautolabs.acaraus.main

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import com.germanautolabs.acaraus.screens.articles.details.articleDetailScreen
import com.germanautolabs.acaraus.screens.articles.details.onNavigateToDetails
import com.germanautolabs.acaraus.screens.articles.list.ARTICLE_LIST_ROUTE
import com.germanautolabs.acaraus.screens.articles.list.articleListScreen

@Composable
fun MainNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
innerPadding: PaddingValues,
route: String = ARTICLE_LIST_ROUTE,
) = NavHost(
navController = navController,
startDestination = route,
modifier = modifier.padding(paddingValues = innerPadding),
) {
articleListScreen(
modifier = modifier,
onNavigateToDetails = navController::onNavigateToDetails,
)

articleDetailScreen(
modifier = modifier,
onNavigateBack = navController::popBackStack,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.germanautolabs.acaraus.models

data class Article(
val id: String,
val source: String,
val title: String,
val description: String?,
val imageURL: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.germanautolabs.acaraus.screens.articles.details

import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.germanautolabs.acaraus.models.Article
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf

const val ARTICLE_DETAIL_ROUTE = "article-detail"
private const val ARTICLE_ID_PARAM = "article-id"

fun NavController.onNavigateToDetails(article: Article) =
navigate("$ARTICLE_DETAIL_ROUTE/?$ARTICLE_ID_PARAM=${article.id}")

fun NavGraphBuilder.articleDetailScreen(
modifier: Modifier = Modifier,
onNavigateBack: () -> Unit,
) {
composable(route = "$ARTICLE_DETAIL_ROUTE/?$ARTICLE_ID_PARAM={$ARTICLE_ID_PARAM}") { backStack ->
val articleId = backStack.arguments?.getString(ARTICLE_ID_PARAM)
val vm = koinViewModel<ArticleDetailViewModel> { parametersOf(articleId) }
ArticleDetailScreen(
modifier = modifier,
vm = vm,
onNavigateBack = onNavigateBack,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.germanautolabs.acaraus.screens.articles.details

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun ArticleDetailScreen(
modifier: Modifier = Modifier,
vm: ArticleDetailViewModel,
onNavigateBack: () -> Unit,
) = Column(modifier = modifier) {
Text("Article Detail Screen article: ${vm.articleId}")
Button(onClick = onNavigateBack) {
Text("Close")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.germanautolabs.acaraus.screens.articles.details

import androidx.lifecycle.ViewModel
import org.koin.android.annotation.KoinViewModel
import org.koin.core.annotation.InjectedParam

@KoinViewModel
class ArticleDetailViewModel(
@InjectedParam val articleId: String,
) : ViewModel()
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.germanautolabs.acaraus.screens.articles.list

import androidx.compose.ui.Modifier
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.germanautolabs.acaraus.models.Article
import org.koin.androidx.compose.koinViewModel

const val ARTICLE_LIST_ROUTE = "article-list"

fun NavGraphBuilder.articleListScreen(
modifier: Modifier = Modifier,
onNavigateToDetails: (article: Article) -> Unit,
) {
composable(route = ARTICLE_LIST_ROUTE) {
val vm = koinViewModel<ArticleListViewModel>()
ArticleListScreen(
modifier = modifier,
vm = vm,
onNavigateToDetails = onNavigateToDetails,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.germanautolabs.acaraus.screens.articles.list

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.germanautolabs.acaraus.models.Article

@Composable
fun ArticleListScreen(
modifier: Modifier = Modifier,
vm: ArticleListViewModel,
onNavigateToDetails: (article: Article) -> Unit,
) = Column(modifier = modifier) {
Text("Article List Screen")
LazyColumn(
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
items(vm.list) { article ->
ArticleListItem(
article = article,
onNavigateToDetails = onNavigateToDetails,
)
}
}
}

@Composable
fun ArticleListItem(
modifier: Modifier = Modifier,
article: Article,
onNavigateToDetails: (article: Article) -> Unit,
) = Card(onClick = { onNavigateToDetails(article) }) {
Column(modifier = modifier.padding(8.dp)) {
Text("Title: ${article.title}")
Text("Description: ${article.description}")
Text("Source: ${article.source}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.germanautolabs.acaraus.screens.articles.list

import androidx.lifecycle.ViewModel
import com.germanautolabs.acaraus.models.Article
import org.koin.android.annotation.KoinViewModel

@KoinViewModel
class ArticleListViewModel : ViewModel() {

private val defaultArticle = Article(
id = "0",
title = "Old news",
description = "Everything new is a well-forgotten old",
source = "Internet",
imageURL = null,
)

val list = listOf(
defaultArticle,
defaultArticle.copy(id = "1", title = "New news 1"),
defaultArticle.copy(id = "2", title = "New news 2"),
defaultArticle.copy(id = "3", title = "New news 3"),
defaultArticle.copy(id = "4", title = "New news 4"),
)
}
Loading

0 comments on commit 9d5f5e8

Please sign in to comment.