refactor: jetpack compose(2/n)

This commit is contained in:
AnranYus
2024-06-14 01:05:11 +08:00
parent dee0b7e73d
commit 6b79f68d92
5 changed files with 81 additions and 13 deletions
+1
View File
@@ -50,6 +50,7 @@ android {
}
dependencies {
implementation("com.squareup.okhttp3:logging-interceptor:4.9.1")
implementation 'androidx.preference:preference:1.2.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'androidx.activity:activity-compose:1.8.2'
+5 -4
View File
@@ -17,6 +17,11 @@
android:exported="true"
android:label="@string/title_activity_post"
android:theme="@style/Theme.Material3.DayNight.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
@@ -37,11 +42,7 @@
<activity
android:name=".ui.activity.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
@@ -1,5 +1,7 @@
package com.lsp.view.repository.network.retrofit
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
@@ -12,8 +14,16 @@ object ServiceCreator {
*
*/
fun <T> create(serviceClass: Class<T>, source: String): T {
val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
val client = OkHttpClient.Builder().addInterceptor(loggingInterceptor).build()
val retrofit = Retrofit.Builder()
.baseUrl(source)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
return retrofit.create(serviceClass)
@@ -3,26 +3,43 @@ package com.lsp.view.ui.compose
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import com.lsp.view.bean.Post
import com.lsp.view.ui.compose.theme.LspViewTheme
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import coil.compose.SubcomposeAsyncImage
import coil.compose.SubcomposeAsyncImageContent
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
private const val TAG = "Compose_PostActivity"
class PostActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -41,16 +58,40 @@ class PostActivity : ComponentActivity() {
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun PostList(viewModel: PostViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsState()
val postList by viewModel.postData.collectAsState()
val listState = rememberLazyStaggeredGridState()
LaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo }
.map { layoutInfo ->
layoutInfo.visibleItemsInfo.lastOrNull()?.index == postList.lastIndex
}
.distinctUntilChanged()
.collect { reachedEnd ->
//避免初次加载数据时,list未绘制导致被判断为到达底部
if (reachedEnd && listState.firstVisibleItemIndex != 0) {
viewModel.fetchPost()
}
}
}
LazyVerticalStaggeredGrid(
state = listState,
columns = StaggeredGridCells.Adaptive(200.dp),
verticalItemSpacing = 4.dp,
horizontalArrangement = Arrangement.spacedBy(4.dp),
content = {
items(postList) {
PostItem(it)
items(items=postList, key = {
it.postId//提供key以保持列表顺序稳定
}) {
Row(Modifier.animateItemPlacement(tween(durationMillis = 250))) {
PostItem(it)
}
}
}
)
@@ -59,10 +100,26 @@ fun PostList(viewModel: PostViewModel = viewModel()) {
@Composable
fun PostItem(post:Post){
AsyncImage(
SubcomposeAsyncImage(
model = post.sampleUrl,
contentScale = ContentScale.Crop,
contentDescription = null,
modifier = Modifier.fillMaxWidth().wrapContentHeight()
loading ={
Box(modifier = Modifier
.fillMaxWidth()
.height(300.dp)) {
CircularProgressIndicator(
modifier = Modifier
.size(50.dp)
.align(Alignment.Center))
}
},
success = {
SubcomposeAsyncImageContent()
},
modifier = Modifier
.clip(RoundedCornerShape(5.dp))
.fillMaxWidth()
.wrapContentHeight()
)
}
@@ -1,6 +1,5 @@
package com.lsp.view.ui.compose
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.lsp.view.bean.YandPost
@@ -36,9 +35,8 @@ class PostViewModel:ViewModel() {
_uiState.value.safeModel,
_uiState.value.page
)
Log.d("PostViewModel",data.size.toString())
postData.value = data
_uiState.value.page ++
postData.value += data
} catch (e: NetworkErrorException) {
//todo network error
}
@@ -46,4 +44,5 @@ class PostViewModel:ViewModel() {
}
}
}