如何实现LazyColumn的Item模板复用?适配Clothes密封接口
Jetpack Compose 复用LazyColumn中Clothes项组件的解决方案
一、核心修改思路
要实现组件复用,关键是将原本依赖LazyColumn项上下文(it)的逻辑,改为通过显式参数传递数据,让ReusableTitleSubtitle组件直接接收Clothes类型的对象,脱离对LazyColumn作用域的依赖。
二、具体修改步骤
1. 改造ReusableTitleSubtitle组件
给组件添加Clothes类型的参数,替代原来隐式的it:
@Composable fun ReusableTitleSubtitle(clothes: Clothes) { val title = stringResource(id = clothes.itemName) val subtitle = when (clothes) { is Clothes.FixedSizeClothing -> stringResource(R.string.size_placeholder, clothes.itemPlaceholder) is Clothes.MultiSizeClothing -> stringResource( R.string.sizes_placeholder_and_placeholder, clothes.itemPlaceholders[0], clothes.itemPlaceholders[1] ) } Column { Text(text = title) Text(text = subtitle) } }
2. 在LazyColumn中调用复用组件
在MyLazyColumn的项lambda中,将当前遍历的Clothes对象(原代码中的it)显式传递给ReusableTitleSubtitle:
MyLazyColumn( lazyItems = clothesItems, modifier = Modifier.padding(contentPadding) ) { // 直接传入当前项的Clothes对象 ReusableTitleSubtitle(it) }
3. 进阶优化(可选):将文本逻辑封装到密封接口
如果希望组件更简洁,可以把生成副标题的逻辑封装到Clothes接口中,避免在组件中写when分支:
sealed interface Clothes { val itemName: Int @Composable fun getSubtitle(): String data class FixedSizeClothing( override val itemName: Int, val itemPlaceholder: Int ) : Clothes { @Composable override fun getSubtitle(): String { return stringResource(R.string.size_placeholder, itemPlaceholder) } } data class MultiSizeClothing( override val itemName: Int, val itemPlaceholders: List<Int> ) : Clothes { @Composable override fun getSubtitle(): String { return stringResource( R.string.sizes_placeholder_and_placeholder, itemPlaceholders[0], itemPlaceholders[1] ) } } }
此时ReusableTitleSubtitle可简化为:
@Composable fun ReusableTitleSubtitle(clothes: Clothes) { Column { Text(text = stringResource(clothes.itemName)) Text(text = clothes.getSubtitle()) } }
三、完整修改后的代码
@Composable fun ReusableTitleSubtitle(clothes: Clothes) { val title = stringResource(id = clothes.itemName) val subtitle = when (clothes) { is Clothes.FixedSizeClothing -> stringResource(R.string.size_placeholder, clothes.itemPlaceholder) is Clothes.MultiSizeClothing -> stringResource( R.string.sizes_placeholder_and_placeholder, clothes.itemPlaceholders[0], clothes.itemPlaceholders[1] ) } Column { Text(text = title) Text(text = subtitle) } } sealed interface Clothes { val itemName: Int data class FixedSizeClothing( override val itemName: Int, val itemPlaceholder: Int ) : Clothes data class MultiSizeClothing( override val itemName: Int, val itemPlaceholders: List<Int> ) : Clothes } @Composable fun MyScreenContent( modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues() ) { Box(modifier = modifier.fillMaxSize()) { val clothesItems = remember { arrayOf( Clothes.FixedSizeClothing(itemName = R.string.chine, itemPlaceholder = 3), Clothes.MultiSizeClothing(itemName = R.string.paisley, itemPlaceholders = listOf(1, 2)), Clothes.FixedSizeClothing(itemName = R.string.stripy, itemPlaceholder = 7), Clothes.FixedSizeClothing(itemName = R.string.tartan, itemPlaceholder = 5), Clothes.FixedSizeClothing(itemName = R.string.tattersall, itemPlaceholder = 8) ) } MyLazyColumn( lazyItems = clothesItems, modifier = Modifier.padding(contentPadding) ) { ReusableTitleSubtitle(it) } } }
内容的提问来源于stack exchange,提问作者wbk727
相关产品推荐
相关产品推荐

