迁移到 Android Jetpack Compose 的第一个理由:告别 RecyclerView 的复杂形式

在传统 Android UI 开发中,RecyclerView 是构建列表 UI 的标配组件,但是当需要处理多种不同类型的 item 时,它的编写成本和维护成本会突然上升。

这不仅是编码的煮烤,还有一堆策略不符 SRP、OCP 等设计原则的问题。

而 Jetpack Compose 的出现,则从根本上解决了这一系列问题,并提供了更现代、声明式、易维护的规划方式。


为什么 RecyclerView 写起来这么累?

  1. 需要重写 getItemViewType(),分类管理 ViewType
  2. onCreateViewHolder() 中进行大量\u whenif 分支
  3. onBindViewHolder() 中再条件判断绑定数据
  4. 每增加一种 item 类型,都需要修改多处代码,异味 SRP 和 OCP
  5. ViewHolder 类内联 UI 和数据的组合,越来越难维护

实际上,一个处理多类型 item 的 Adapter 很容易变成“无限的 if/else” 、“大型 when 场面” 和“一览不清的熟二演示”。


Compose 怎么做到一切都好好的

Jetpack Compose 推行声明式 UI,不再需要 Adapter + XML + ViewHolder 等组合,使用者只需输入“怎么显示”,而不用关心“什么时候显示”。

LazyColumn 直接替代 RecyclerView

Compose 中的 LazyColumn 是用于列表显示的组件,用法极为简洁:

LazyColumn {
    items(myList) { item ->
        when (item) {
            is ListItem.Title -> TitleItem(item)
            is ListItem.Content -> ContentItem(item)
            is ListItem.Image -> ImageItem(item)
        }
    }
}

不再需要:

  • getItemViewType
  • onCreateViewHolder
  • onBindViewHolder
  • Adapter/ViewHolder

你才是 UI 展示的主管,不再是工厂和导演了。


演示 Demo :Compose 下的多类型列表

1. 数据模型

sealed class ListItem {
    data class Title(val text: String) : ListItem()
    data class Content(val description: String) : ListItem()
    data class Image(val url: String) : ListItem()
}

2. UI 组件

@Composable
fun TitleItem(item: ListItem.Title) {
    Text(
        text = item.text,
        style = MaterialTheme.typography.titleLarge,
        modifier = Modifier.padding(16.dp)
    )
}

@Composable
fun ContentItem(item: ListItem.Content) {
    Text(
        text = item.description,
        style = MaterialTheme.typography.bodyMedium,
        modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
    )
}

@Composable
fun ImageItem(item: ListItem.Image) {
    AsyncImage(
        model = item.url,
        contentDescription = null,
        modifier = Modifier
            .fillMaxWidth()
            .height(180.dp)
            .padding(8.dp),
        contentScale = ContentScale.Crop
    )
}

提示:AsyncImage 来自 coil-compose 库,可以用 Glide 或 Accompanist 替代

3. 主组织 UI

@Composable
fun MultiTypeList(items: List<ListItem>) {
    LazyColumn {
        items(items) { item ->
            when (item) {
                is ListItem.Title -> TitleItem(item)
                is ListItem.Content -> ContentItem(item)
                is ListItem.Image -> ImageItem(item)
            }
        }
    }
}

4. ComposeView 引入,实现混合开发

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val sampleData = listOf(
                ListItem.Title("标题 1"),
                ListItem.Content("这是一段内容"),
                ListItem.Image("https://picsum.photos/300/200"),
                ListItem.Title("标题 2"),
                ListItem.Content("这是第二段内容")
            )
            MaterialTheme {
                MultiTypeList(sampleData)
            }
        }
    }
}

总结

传统 RecyclerView 在处理复杂列表时带来不少编码粗重和维护性较差的问题,Jetpack Compose 使用声明式、减少代码、分类精精的方式解决了这一切。

而逐步迁移,可以从 ComposeView 开始,先试验小段代码,再手揣全面迁移。

实现简单,精神不乱。Compose 就是最好的移动 UI 之道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值