Skip to content

Commit 9564b3d

Browse files
Add navigation graph and navigation code
- Add android browser library from custom crome tab
1 parent e7aff81 commit 9564b3d

File tree

13 files changed

+279
-74
lines changed

13 files changed

+279
-74
lines changed

app/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
plugins {
22
id 'com.android.application'
33
id 'org.jetbrains.kotlin.android'
4+
id 'kotlin-parcelize'
45
}
56

67
android {
@@ -70,4 +71,10 @@ dependencies {
7071
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
7172
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
7273

74+
implementation "androidx.navigation:navigation-compose:2.5.3"
75+
implementation 'androidx.browser:browser:1.4.0'
76+
77+
testImplementation 'com.squareup.okhttp3:mockwebserver:4.9.0'
78+
testImplementation 'org.mockito:mockito-core:2.23.0'
79+
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
7380
}

app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,14 @@ package com.lahsuak.apps.jetpackcomposebasic
33
import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
6-
import androidx.compose.foundation.layout.Column
76
import androidx.compose.foundation.layout.fillMaxSize
8-
import androidx.compose.foundation.layout.fillMaxWidth
9-
import androidx.compose.foundation.layout.padding
10-
import androidx.compose.foundation.lazy.LazyColumn
11-
import androidx.compose.foundation.lazy.items
127
import androidx.compose.material3.MaterialTheme
138
import androidx.compose.material3.Surface
14-
import androidx.compose.material3.Text
159
import androidx.compose.runtime.Composable
16-
import androidx.compose.runtime.collectAsState
17-
import androidx.compose.runtime.getValue
1810
import androidx.compose.ui.Modifier
1911
import androidx.compose.ui.tooling.preview.Preview
20-
import androidx.compose.ui.unit.dp
21-
import androidx.lifecycle.ViewModel
22-
import androidx.lifecycle.viewmodel.compose.viewModel
23-
import com.lahsuak.apps.jetpackcomposebasic.model.News
24-
import com.lahsuak.apps.jetpackcomposebasic.ui.NewsItem
25-
import com.lahsuak.apps.jetpackcomposebasic.ui.elements.*
12+
import com.lahsuak.apps.jetpackcomposebasic.ui.MyAppNavHost
2613
import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme
27-
import com.lahsuak.apps.jetpackcomposebasic.ui.viewmodel.NewsViewModel
2814

2915
class MainActivity : ComponentActivity() {
3016
override fun onCreate(savedInstanceState: Bundle?) {
@@ -36,58 +22,13 @@ class MainActivity : ComponentActivity() {
3622
modifier = Modifier.fillMaxSize(),
3723
color = MaterialTheme.colorScheme.background
3824
) {
39-
val newsViewModel: NewsViewModel = viewModel()
40-
newsViewModel.getNews("general")
41-
getNewsData(modifier = Modifier.fillMaxSize(), newsViewModel)
42-
// Column(Modifier.padding(vertical = 16.dp, horizontal = 8.dp)) {
43-
// RadioButtonUI()
44-
// CheckBoxUI("Accept term and condition")
45-
// EditTextUI("Enter your name", modifier = Modifier.fillMaxWidth())
46-
// PasswordFieldUI("Enter your password", modifier = Modifier.fillMaxWidth())
47-
// Search(placeHolderMsg = "Search", modifier = Modifier.fillMaxWidth())
48-
// SnackBarUI("Hello it's me snackbar")
49-
// }
25+
MyAppNavHost()
5026
}
5127
}
5228
}
5329
}
5430
}
5531

56-
@Composable
57-
fun getList(): List<News> {
58-
val list = mutableListOf<News>()
59-
for (i in 0..10) {
60-
list.add(
61-
News(
62-
"Kaushal",
63-
"Ness",
64-
"https://pixabay.com/get/gc5bde75f8a92a997aa842681d52d37e41990f5e639497bad55c1cf9921835528340e1269788a027624b201d17734fb431c5269478e54aece4e65f7581452fe98_640.jpg",
65-
"https://pixabay.com/get/gc5bde75f8a92a997aa842681d52d37e41990f5e639497bad55c1cf9921835528340e1269788a027624b201d17734fb431c5269478e54aece4e65f7581452fe98_640.jpg",
66-
)
67-
)
68-
}
69-
return list
70-
}
71-
72-
@Composable
73-
fun getNewsData(
74-
modifier: Modifier,
75-
newsViewModel: NewsViewModel
76-
) {
77-
val newsList by newsViewModel.newsFlow.collectAsState()
78-
// val d = getList()
79-
LazyColumn(modifier = modifier.padding(vertical = 4.dp)) {
80-
items(items = newsList) { news ->
81-
NewsItem(news = news)
82-
}
83-
}
84-
}
85-
86-
@Composable
87-
fun Greeting(name: String) {
88-
Text(text = "Hello $name!")
89-
}
90-
9132
@Preview(showBackground = true)
9233
@Composable
9334
fun DefaultPreview() {
@@ -96,10 +37,7 @@ fun DefaultPreview() {
9637
modifier = Modifier.fillMaxSize(),
9738
color = MaterialTheme.colorScheme.background
9839
) {
99-
RadioButtonUI()
100-
CheckBoxUI("Accept term and condition")
101-
EditTextUI("Enter your name", modifier = Modifier.fillMaxWidth())
102-
PasswordFieldUI("Enter your password", modifier = Modifier.fillMaxWidth())
40+
MyAppNavHost()
10341
}
10442
}
10543
}

app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/api/NewApi.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.lahsuak.apps.jetpackcomposebasic.api
22

33
import com.lahsuak.apps.jetpackcomposebasic.model.News
44
import com.lahsuak.apps.jetpackcomposebasic.model.NewsParentModel
5+
import retrofit2.Response
56
import retrofit2.http.GET
67
import retrofit2.http.Path
78
import retrofit2.http.Query
@@ -17,4 +18,10 @@ interface NewApi {
1718
// @Path("category")
1819
// category: String
1920
): NewsParentModel
21+
22+
@GET("/NewsAPI/top-headlines/category/general/in.json")
23+
suspend fun getNews2(
24+
// @Path("category")
25+
// category: String
26+
): Response<NewsParentModel>
2027
}
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.lahsuak.apps.jetpackcomposebasic.model
22

3-
data class News (
4-
val description:String,
5-
val title:String,
6-
val url:String,
7-
val urlToImage:String,
8-
)
3+
import android.os.Parcelable
4+
import kotlinx.parcelize.Parcelize
5+
6+
@Parcelize
7+
data class News(
8+
val description: String,
9+
val title: String,
10+
val url: String,
11+
val urlToImage: String,
12+
) : Parcelable
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.lahsuak.apps.jetpackcomposebasic.ui
2+
3+
import android.content.Context
4+
import android.net.Uri
5+
import androidx.browser.customtabs.CustomTabsIntent
6+
7+
fun openTab(context: Context, url: String) {
8+
val packageName = "com.android.chrome"
9+
val builder = CustomTabsIntent.Builder()
10+
builder.setShowTitle(true)
11+
builder.setInstantAppsEnabled(true)
12+
val customBuilder = builder.build()
13+
customBuilder.intent.setPackage(packageName)
14+
customBuilder.launchUrl(context, Uri.parse(url))
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.lahsuak.apps.jetpackcomposebasic.ui
2+
3+
import java.io.InputStreamReader
4+
5+
object Helper {
6+
fun readFileResource(fileName: String): String{
7+
val inputStream = Helper::class.java.getResourceAsStream(fileName)
8+
val builder = StringBuilder()
9+
val reader = InputStreamReader(inputStream,Charsets.UTF_8)
10+
reader.readLines().forEach{
11+
builder.append(it)
12+
}
13+
return builder.toString()
14+
}
15+
}
16+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.lahsuak.apps.jetpackcomposebasic.ui
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.ui.Modifier
5+
import androidx.lifecycle.viewmodel.compose.viewModel
6+
import androidx.navigation.NavHostController
7+
import androidx.navigation.compose.NavHost
8+
import androidx.navigation.compose.composable
9+
import androidx.navigation.compose.rememberNavController
10+
import com.lahsuak.apps.jetpackcomposebasic.model.News
11+
import com.lahsuak.apps.jetpackcomposebasic.ui.detailscreen.DetailScreen
12+
import com.lahsuak.apps.jetpackcomposebasic.ui.home.HomeScreen
13+
import com.lahsuak.apps.jetpackcomposebasic.ui.viewmodel.NewsViewModel
14+
15+
@Composable
16+
fun MyAppNavHost(
17+
modifier: Modifier = Modifier,
18+
navController: NavHostController = rememberNavController(),
19+
startDestination: String = NavigationItem.Home.route
20+
) {
21+
NavHost(
22+
modifier = modifier,
23+
navController = navController,
24+
startDestination = startDestination
25+
) {
26+
composable(NavigationItem.Home.route) {
27+
val newsViewModel: NewsViewModel = viewModel()
28+
newsViewModel.getNews("general")
29+
HomeScreen(
30+
navController, newsViewModel
31+
)
32+
}
33+
composable(NavigationItem.Details.route) {
34+
val news =
35+
navController.previousBackStackEntry?.savedStateHandle?.get<News>("news")
36+
DetailScreen(text = news?.url?:"")
37+
}
38+
}
39+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.lahsuak.apps.jetpackcomposebasic.ui
2+
3+
sealed class NavigationItem(val route: String) {
4+
object Home : NavigationItem("home")
5+
object Details : NavigationItem("details")
6+
}

app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/NewsItem.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.lahsuak.apps.jetpackcomposebasic.ui
22

33
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.clickable
45
import androidx.compose.foundation.layout.*
56
import androidx.compose.material3.MaterialTheme
67
import androidx.compose.material3.Surface
@@ -13,14 +14,15 @@ import androidx.compose.ui.platform.LocalContext
1314
import androidx.compose.ui.text.style.TextOverflow
1415
import androidx.compose.ui.tooling.preview.Preview
1516
import androidx.compose.ui.unit.dp
17+
import androidx.navigation.NavController
1618
import coil.compose.rememberAsyncImagePainter
1719
import coil.request.ImageRequest
1820
import com.lahsuak.apps.jetpackcomposebasic.R
1921
import com.lahsuak.apps.jetpackcomposebasic.model.News
2022
import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme
2123

2224
@Composable
23-
fun NewsItem(news: News) {
25+
fun NewsItem(news: News, onClick: () -> Unit) {
2426
val painter = rememberAsyncImagePainter(
2527
model = ImageRequest.Builder(LocalContext.current)
2628
.data(news.urlToImage)
@@ -29,7 +31,9 @@ fun NewsItem(news: News) {
2931
.build(),
3032
contentScale = ContentScale.FillWidth
3133
)
32-
Column(modifier = Modifier.fillMaxWidth()) {
34+
Column(modifier = Modifier.fillMaxWidth().clickable {
35+
onClick()
36+
}) {
3337
Image(
3438
painter = painter,
3539
contentDescription = null,
@@ -71,7 +75,7 @@ fun NewsItemPreview() {
7175
"https://pixabay.com/get/gc5bde75f8a92a997aa842681d52d37e41990f5e639497bad55c1cf9921835528340e1269788a027624b201d17734fb431c5269478e54aece4e65f7581452fe98_640.jpg",
7276
"https://pixabay.com/get/gc5bde75f8a92a997aa842681d52d37e41990f5e639497bad55c1cf9921835528340e1269788a027624b201d17734fb431c5269478e54aece4e65f7581452fe98_640.jpg",
7377
)
74-
)
78+
) {}
7579
}
7680
}
7781
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.lahsuak.apps.jetpackcomposebasic.ui.detailscreen
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.material3.Text
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.ui.Modifier
7+
import androidx.compose.ui.platform.LocalContext
8+
import com.lahsuak.apps.jetpackcomposebasic.ui.openTab
9+
10+
@Composable
11+
fun DetailScreen(text: String) {
12+
val context = LocalContext.current
13+
Text(text = text, Modifier.clickable {
14+
openTab(context, text)
15+
})
16+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.lahsuak.apps.jetpackcomposebasic.ui.home
2+
3+
import androidx.compose.foundation.layout.padding
4+
import androidx.compose.foundation.lazy.LazyColumn
5+
import androidx.compose.foundation.lazy.items
6+
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.collectAsState
8+
import androidx.compose.runtime.getValue
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.unit.dp
11+
import androidx.navigation.NavController
12+
import com.lahsuak.apps.jetpackcomposebasic.model.News
13+
import com.lahsuak.apps.jetpackcomposebasic.ui.NewsItem
14+
import com.lahsuak.apps.jetpackcomposebasic.ui.viewmodel.NewsViewModel
15+
16+
@Composable
17+
fun HomeScreen(
18+
navController: NavController,
19+
newsViewModel: NewsViewModel
20+
) {
21+
22+
val newsList by newsViewModel.newsFlow.collectAsState()
23+
LazyColumn(modifier = Modifier.padding(vertical = 4.dp)) {
24+
items(items = newsList) { news ->
25+
NewsItem(
26+
news = news,
27+
) {
28+
navController.currentBackStackEntry?.savedStateHandle?.set("news", news)
29+
navController.navigate("details")
30+
}
31+
}
32+
}
33+
}
34+
35+
@Composable
36+
fun getList(): List<News> {
37+
val list = mutableListOf<News>()
38+
for (i in 0..10) {
39+
list.add(
40+
News(
41+
"Kaushal",
42+
"Ness",
43+
"https://pixabay.com/get/gc5bde75f8a92a997aa842681d52d37e41990f5e639497bad55c1cf9921835528340e1269788a027624b201d17734fb431c5269478e54aece4e65f7581452fe98_640.jpg",
44+
"https://pixabay.com/get/gc5bde75f8a92a997aa842681d52d37e41990f5e639497bad55c1cf9921835528340e1269788a027624b201d17734fb431c5269478e54aece4e65f7581452fe98_640.jpg",
45+
)
46+
)
47+
}
48+
return list
49+
}

0 commit comments

Comments
 (0)