xvl*_*aze 4 android lazy-loading kotlin retrofit2 android-jetpack-compose
我对 Jetpack Compose 和 Kotlin 完全陌生,但对 Java 中的 Android 开发并不熟悉。想要第一次接触这两种技术,我想制作一个非常简单的应用程序,用来自Dog API的图像填充 LazyColumn 。
所有改造连接部分都工作正常,因为我已经设法用随机小狗填充一张卡片,但是当需要填充列表时,这是不可能的。发生的情况是这样的:
dogImages自动更新。你有什么想法?我找不到关于这个问题的任何教程,只是关于滚动监听状态的模糊解释。
这是我的代码:
class MainActivity : ComponentActivity() {
private val dogImages = mutableStateListOf<String>()
@ExperimentalCoilApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PuppyWallpapersTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
DogList(dogImages)
searchByName("poodle")
}
}
}
}
private fun getRetrofit():Retrofit {
return Retrofit.Builder()
.baseUrl("https://dog.ceo/api/breed/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
private fun searchByName(query: String) {
CoroutineScope(Dispatchers.IO).launch {
val call = getRetrofit().create(APIService::class.java).getDogsByBreed("$query/images")
val puppies = call.body()
runOnUiThread {
if (call.isSuccessful) {
val images = puppies?.images ?: emptyList()
dogImages.clear()
dogImages.addAll(images)
}
}
}
}
@ExperimentalCoilApi
@Composable
fun DogList(dogs: SnapshotStateList<String>) {
LazyColumn() {
items(dogs) { dog ->
DogCard(dog)
}
}
}
@ExperimentalCoilApi
@Composable
fun DogCard(dog: String) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp),
elevation = 10.dp
) {
Image(
painter = rememberImagePainter(dog),
contentDescription = null
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
先感谢您!:)
Phi*_*hov 10
您的图像视图无法确定加载之前的纵横比,并且它不会开始加载,因为计算出的高度为零。请参阅此回复以获取更多信息。
还有一些关于您的代码的提示。
MainActivity是不好的做法,您可以使用视图模型。在视图模型中,您可以使用viewModelScope,它将绑定到您的屏幕:所有任务都将被取消,并且当屏幕关闭时对象将被销毁。searchByName. 该代码在重组过程中可能会被多次调用,因此您的调用将是重复的。你应该这样做,但会有副作用。在这种情况下,您可以使用LaunchedEffect,但您也可以在init视图模型中执行此操作,因为它将在屏幕出现时创建。MainActivity并不是很方便。一个好的做法是将它们简单地存储在一个文件中,并通过文件在逻辑上将它们分开。您的代码可以更新为以下内容:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PuppyWallpapersTheme {
DogsListScreen()
}
}
}
}
@Composable
fun DogsListScreen(
// pass the view model in this form for convenient testing
viewModel: DogsModel = viewModel()
) {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
DogList(viewModel.dogImages)
}
}
@Composable
fun DogList(dogs: SnapshotStateList<String>) {
LazyColumn {
items(dogs) { dog ->
DogCard(dog)
}
}
}
@Composable
fun DogCard(dog: String) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(15.dp),
elevation = 10.dp
) {
Image(
painter = rememberImagePainter(
data = dog,
builder = {
// don't use it blindly, it can be tricky.
// check out /sf/answers/4823587471/
size(OriginalSize)
},
),
contentDescription = null,
)
}
}
class DogsModel : ViewModel() {
val dogImages = mutableStateListOf<String>()
init {
searchByName("poodle")
}
private fun getRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://dog.ceo/api/breed/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
private fun searchByName(query: String) {
viewModelScope
.launch {
val call = getRetrofit()
.create(APIService::class.java)
.getDogsByBreed("$query/images")
val puppies = call.body()
if (call.isSuccessful) {
val images = puppies?.images ?: emptyList()
dogImages.clear()
dogImages.addAll(images)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6455 次 |
| 最近记录: |