Skip to content

Commit ab4b84f

Browse files
committed
update
1 parent 42a140f commit ab4b84f

File tree

10 files changed

+192
-36
lines changed

10 files changed

+192
-36
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ dependencies {
7070
implementation(libs.ktor.client.content.negotiation)
7171
implementation(libs.ktor.serialization.kotlinx.json)
7272

73-
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
73+
implementation(libs.logging.interceptor)
74+
implementation(libs.coil)
7475

7576
testImplementation(libs.junit)
7677
androidTestImplementation(libs.androidx.test.ext.junit)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.wzq.jd.compose.app.data
2+
3+
import kotlinx.serialization.Serializable
4+
5+
@Serializable
6+
data class KnowledgeCategories(
7+
val articleList: List<ArticleItem>,
8+
val author: String,
9+
val children: List<KnowledgeCategories>,
10+
val courseId: Int,
11+
val cover: String,
12+
val desc: String,
13+
val id: Int,
14+
val lisense: String,
15+
val lisenseLink: String,
16+
val name: String,
17+
val order: Int,
18+
val parentChapterId: Int,
19+
val type: Int,
20+
val userControlSetTop: Boolean,
21+
val visible: Int
22+
)

app/src/main/java/com/wzq/jd/compose/app/data/NetResult.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@ data class NetResult<T>(
1313
val errorCode: Int,
1414
val errorMsg: String
1515
)
16+
1617
@Serializable
1718
data class NetResultList<T>(
19+
val data: ResultList<T>,
20+
val errorCode: Int,
21+
val errorMsg: String
22+
)
23+
24+
@Serializable
25+
data class ResultList<T>(
1826
val curPage: Int,
1927
@SerialName("datas")
2028
val listData: List<T>,
@@ -24,3 +32,4 @@ data class NetResultList<T>(
2432
val size: Int,
2533
val total: Int
2634
)
35+

app/src/main/java/com/wzq/jd/compose/app/data/NetworkUtil.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package com.wzq.jd.compose.app.data
22

33
import io.ktor.client.HttpClient
4-
import io.ktor.client.call.body
54
import io.ktor.client.engine.okhttp.OkHttp
65
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
7-
import io.ktor.client.request.get
86
import io.ktor.serialization.kotlinx.json.json
97
import kotlinx.serialization.json.Json
108
import okhttp3.logging.HttpLoggingInterceptor
@@ -15,14 +13,6 @@ import okhttp3.logging.HttpLoggingInterceptor
1513
*/
1614
object NetworkUtil {
1715

18-
object Url {
19-
const val HomeArticleList = "https://www.wanandroid.com/article/list/0/json"
20-
}
21-
22-
suspend inline fun <reified T> requestGet(url: String): T {
23-
return client.get(url).body()
24-
}
25-
2616
val client by lazy {
2717
HttpClient(OkHttp) {
2818
engine {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.wzq.jd.compose.app.data
2+
3+
import io.ktor.client.call.body
4+
import io.ktor.client.request.get
5+
6+
/**
7+
* create by wzq on 2023/12/1
8+
*
9+
*/
10+
object RemoteDataRepo {
11+
12+
private const val BASE_URL = "https://www.wanandroid.com/"
13+
private const val HOME_ARTICLE_LIST = "${BASE_URL}article/list/0/json"
14+
private const val KNOWLEDGE_CATEGORIES = "${BASE_URL}tree/json"
15+
private const val PROJECT_LIST = "${BASE_URL}article/listproject/0/json"
16+
17+
private val httpClient get() = NetworkUtil.client
18+
19+
private val defaultErrorHandler = fun(exception: Throwable) {
20+
exception.printStackTrace()
21+
}
22+
23+
suspend fun getHomeArticleList() = httpClient.runCatching {
24+
get(HOME_ARTICLE_LIST).body<NetResultList<ArticleItem>>()
25+
}.onFailure(defaultErrorHandler)
26+
27+
suspend fun getProjectList() = httpClient.runCatching {
28+
get(PROJECT_LIST).body<NetResultList<ArticleItem>>()
29+
}.onFailure(defaultErrorHandler)
30+
31+
suspend fun getKnowledgeCategories() = runCatching {
32+
httpClient.get(KNOWLEDGE_CATEGORIES).body<NetResultList<KnowledgeCategories>>()
33+
}.onFailure(defaultErrorHandler)
34+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.wzq.jd.compose.app.page
2+
3+
import androidx.compose.runtime.Composable
4+
5+
/**
6+
* create by wzq on 2023/12/1
7+
*
8+
*/
9+
@Composable
10+
fun CategoriesPage() {
11+
}

app/src/main/java/com/wzq/jd/compose/app/page/HomePage.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import androidx.compose.runtime.LaunchedEffect
77
import androidx.compose.runtime.mutableStateListOf
88
import androidx.compose.runtime.remember
99
import com.wzq.jd.compose.app.data.ArticleItem
10-
import com.wzq.jd.compose.app.data.NetResult
11-
import com.wzq.jd.compose.app.data.NetResultList
12-
import com.wzq.jd.compose.app.data.NetworkUtil
10+
import com.wzq.jd.compose.app.data.RemoteDataRepo
1311

1412
/**
1513
* create by wzq on 2023/11/27
@@ -21,12 +19,8 @@ fun HomePage() {
2119
mutableStateListOf<ArticleItem>()
2220
}
2321
LaunchedEffect(key1 = true, block = {
24-
try {
25-
val response: NetResult<NetResultList<ArticleItem>> =
26-
NetworkUtil.requestGet(NetworkUtil.Url.HomeArticleList)
27-
data.addAll(response.data.listData)
28-
} catch (e: Exception) {
29-
e.printStackTrace()
22+
RemoteDataRepo.getHomeArticleList().onSuccess {
23+
data.addAll(it.data.listData)
3024
}
3125
})
3226

app/src/main/java/com/wzq/jd/compose/app/page/MainPage.kt

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@file:OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
2-
31
package com.wzq.jd.compose.app.page
42

53
import androidx.compose.foundation.ExperimentalFoundationApi
@@ -32,33 +30,36 @@ import kotlinx.coroutines.launch
3230
* create by wzq on 2023/11/24
3331
*
3432
*/
33+
@OptIn(ExperimentalFoundationApi::class)
3534
@Composable
3635
fun MainPage(navController: NavHostController) {
3736
val pagerState = rememberPagerState { 3 }
38-
Scaffold(
39-
topBar = {
40-
MainTopBar(navController)
41-
},
42-
bottomBar = {
43-
MainBottomBar(pagerState)
44-
}
45-
) { paddingValues ->
37+
Scaffold(topBar = {
38+
MainTopBar(navController)
39+
}, bottomBar = {
40+
MainBottomBar(pagerState)
41+
}) { paddingValues ->
4642
HorizontalPager(
4743
state = pagerState,
4844
modifier = Modifier
4945
.padding(paddingValues)
50-
.background(color = MaterialTheme.colorScheme.background)
51-
) {
52-
when (it) {
46+
.background(color = MaterialTheme.colorScheme.background),
47+
beyondBoundsPageCount = 3
48+
) { page ->
49+
println(page)
50+
when (page) {
5351
0 -> HomePage()
52+
1 -> ProjectPage()
53+
2 -> CategoriesPage()
5454
else -> {
55-
Text(text = "page at : $it")
55+
throw Exception("Shouldn't Happen!")
5656
}
5757
}
5858
}
5959
}
6060
}
6161

62+
@OptIn(ExperimentalFoundationApi::class)
6263
@Composable
6364
fun MainBottomBar(pagerState: PagerState) {
6465
val coroutineScope = rememberCoroutineScope()
@@ -88,6 +89,7 @@ fun MainBottomBar(pagerState: PagerState) {
8889
}
8990
}
9091

92+
@OptIn(ExperimentalMaterial3Api::class)
9193
@Composable
9294
fun MainTopBar(navController: NavHostController) {
9395
CenterAlignedTopAppBar(
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.wzq.jd.compose.app.page
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.PaddingValues
7+
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.staggeredgrid.LazyVerticalStaggeredGrid
11+
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
12+
import androidx.compose.foundation.lazy.staggeredgrid.items
13+
import androidx.compose.material3.Card
14+
import androidx.compose.material3.ExperimentalMaterial3Api
15+
import androidx.compose.material3.MaterialTheme
16+
import androidx.compose.material3.Text
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.runtime.LaunchedEffect
19+
import androidx.compose.runtime.mutableStateListOf
20+
import androidx.compose.runtime.remember
21+
import androidx.compose.ui.Alignment
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.graphics.Color
24+
import androidx.compose.ui.layout.ContentScale
25+
import androidx.compose.ui.platform.LocalContext
26+
import androidx.compose.ui.unit.dp
27+
import coil.compose.AsyncImage
28+
import com.wzq.jd.compose.app.WebActivity
29+
import com.wzq.jd.compose.app.data.ArticleItem
30+
import com.wzq.jd.compose.app.data.RemoteDataRepo
31+
32+
/**
33+
* create by wzq on 2023/12/1
34+
*
35+
*/
36+
@Composable
37+
fun ProjectPage() {
38+
val data = remember {
39+
mutableStateListOf<ArticleItem>()
40+
}
41+
LaunchedEffect(key1 = true, block = {
42+
RemoteDataRepo.getProjectList().onSuccess {
43+
data.addAll(it.data.listData)
44+
}
45+
})
46+
47+
val context = LocalContext.current
48+
LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Fixed(2),
49+
contentPadding = PaddingValues(8.dp),
50+
verticalItemSpacing = 8.dp,
51+
horizontalArrangement = Arrangement.spacedBy(8.dp),
52+
content = {
53+
items(data) {
54+
ProjectItem(item = it) {
55+
WebActivity.open(context, it.link)
56+
}
57+
}
58+
})
59+
60+
}
61+
62+
@OptIn(ExperimentalMaterial3Api::class)
63+
@Composable
64+
fun ProjectItem(item: ArticleItem, onItemClick: () -> Unit) {
65+
Card(modifier = Modifier.fillMaxWidth(), onClick = onItemClick) {
66+
Box(modifier = Modifier.fillMaxSize()) {
67+
AsyncImage(
68+
model = item.envelopePic,
69+
contentDescription = null,
70+
modifier = Modifier.fillMaxWidth(),
71+
contentScale = ContentScale.FillWidth
72+
)
73+
Box(
74+
modifier = Modifier
75+
.fillMaxWidth()
76+
.background(Color(0x81000000))
77+
.align(Alignment.BottomStart)
78+
) {
79+
Text(
80+
text = item.title,
81+
maxLines = 2,
82+
style = MaterialTheme.typography.titleMedium,
83+
modifier = Modifier.padding(8.dp)
84+
)
85+
}
86+
87+
}
88+
89+
}
90+
}

gradle/libs.versions.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,21 @@ compose-bom = "2023.10.01"
1313

1414
ktor-client-core = "2.3.6"
1515

16-
coil = "2.4.0"
16+
coil = "2.5.0"
1717

1818
junit = "4.13.2"
1919
androidx-test-ext-junit = "1.1.5"
2020
espresso-core = "3.5.1"
21+
logging-interceptor = "4.12.0"
2122
navigation-compose = "2.7.5"
2223

2324
[libraries]
2425
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation-compose" }
2526
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
2627
core-ktx = { module = "androidx.core:core-ktx", version.ref = "core-ktx" }
27-
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
28+
29+
coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
30+
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "logging-interceptor" }
2831

2932
lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-ktx" }
3033
activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity-compose" }

0 commit comments

Comments
 (0)