kotlin 手机轮替后才出现新卡项

cwxwcias  于 2023-02-19  发布在  Kotlin
关注(0)|答案(1)|浏览(137)

我正在为我的猫写一个小的图库应用程序。它有一个按钮,通过点击它,一个新的照片项目被添加到显示列表中,但它只出现在手机旋转后,我希望它出现在屏幕上的权利后,按钮被点击。
现在,所有内容都存储在savedStateHandle.getStateFlow中的一个mutableList中,但我也尝试了常规的MutableStateFlow和mutableStateOf,但没有帮助。
应用程序

@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun BebrasPhotosApp() {
    val galaryViewModel = viewModel<GalaryViewModel>()
    val allPhotos by galaryViewModel.loadedPics.collectAsState()
    Scaffold(topBar = { BebraTopAppBar() }, floatingActionButton = {
        FloatingActionButton(
            onClick = { galaryViewModel.addPicture() },
            backgroundColor = MaterialTheme.colors.onBackground
        ) {
            Icon(
                imageVector = Icons.Rounded.Add,
                contentDescription = "Add Photo",
                tint = Color.White,
            )
        }
    }) {
        LazyColumn(modifier = Modifier.background(color = MaterialTheme.colors.background)) {
            items(allPhotos) {
                PhotoItem(bebra = it)
            }
        }
    }

}

视图模型

class GalaryViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
        val loadedPics = savedStateHandle.getStateFlow(
        "pics", initialValue = mutableListOf<Bebra>(
            Bebra(R.string.photo_1, R.string.desc_1, R.drawable.bebra_pic_1, R.string.add_desc_1),
            Bebra(R.string.photo_2, R.string.desc_2, R.drawable.bebra_pic_2, R.string.add_desc_2),
            Bebra(R.string.photo_3, R.string.desc_3, R.drawable.bebra_pic_3, R.string.add_desc_3)
        )
    )


    fun addPicture() {
        val additionalBebraPhoto = Bebra(
            R.string.photo_placeholder,
            R.string.desc_placeholder,
            R.drawable.placeholder_cat,
            R.string.add_desc_placeholder
        )
        savedStateHandle.get<MutableList<Bebra>>("pics")!!.add(additionalBebraPhoto)
    }
}

照片项目

@Composable
fun PhotoItem(bebra: Bebra, modifier: Modifier = Modifier) {
    var expanded by remember { mutableStateOf(false) }
    Card(elevation = 4.dp, modifier = modifier
        .padding(8.dp)
        .clickable { expanded = !expanded }) {
        Column(
            modifier = modifier
                .padding(8.dp)
                .animateContentSize(
                    animationSpec = spring(
                        dampingRatio = Spring.DampingRatioMediumBouncy,
                        stiffness = Spring.StiffnessLow
                    )
                )
        ) {
            Text(
                text = stringResource(id = bebra.PicNumber),
                style = MaterialTheme.typography.h1,
                modifier = modifier.padding(bottom = 8.dp)
            )
            Text(
                text = stringResource(id = bebra.PicDesc),
                style = MaterialTheme.typography.body1,
                modifier = modifier.padding(bottom = 8.dp)
            )
            Image(
                painter = painterResource(id = bebra.Picture),
                contentDescription = stringResource(id = bebra.PicDesc),
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(256.dp)
                    .clip(RoundedCornerShape(12))
            )
            if (expanded) {
                BebraAdditionalDesc(bebra.additionalDesc)
            }
        }

    }
}

Bebra数据类

data class Bebra(
    @StringRes val PicNumber: Int,
    @StringRes val PicDesc: Int,
    @DrawableRes val Picture: Int,
    @StringRes val additionalDesc: Int
)
plicqrtu

plicqrtu1#

所以,我也不是非常熟悉JC,但乍一看,它看起来像你的方法addPicture()-当用户点击按钮时调用,不更新状态,因此没有发生重组,所以UI不更新。
检查:

fun addPicture() {
        // ...

        savedStateHandle.get<MutableList<Bebra>>("pics")!!.add(additionalBebraPhoto)
}

因此,这里基本上是向savedStateHandle添加一个新项,我假设这不会触发重新组合。
我认为你需要做的是,以某种方式更新loadedPics
然而,loadedPicsStateFlow,要能够更新它,您需要MutableStateFlow
为了简单起见,如果您正在操作一个字符串列表,您将这样做:

// declare MutableStateFlow that can be updated and trigger recomposition
val _loadedPics = MutableStateFlow(
     savedStateHandle.get<MutableList<String>>("pics") ?: mutableListOf()
)

// use this in the JC layout to listen to state changes        
val loadedPics: StateFlow<List<String>> = _loadedPics
        
// addPicture:
val prevList = _loadedPics.value
prevList.add("item")

_loadedPics.value = prevList // triggers recomposition

// here you probably will want to save the item in the
// `savedStateHandle` as you already doing.

相关问题