admin管理员组文章数量:1794759
MDC和Compose: 轮播图的两种实现
一、项目背景:
介绍MDC(Android View) Carousel UI
Material Design Components (MDC) 是构建现代 Android 应用的 UI 组件库,遵循 Google 的 Material Design 规范。而轮播图(Carousel)是现代 UI 中常见的功能之一,展示图片、商品列表等内容时非常有用。
参考资料:Material Design Components for Android 1.9.0 - Material Design
二、项目开发
2.7.1 项目配置
代码语言:javascript代码运行次数:0运行复制dependencies {
implementation libs.androidx.core.ktx
implementation libs.androidx.appcompat
implementation libs.material
implementation libs.androidx.activity
implementation libs.androidx.constraintlayout
implementation libs.androidx.recyclerview
testImplementation libs.junit
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.androidx.espresso.core
implementation libs.material.v190
implementation libs.androidx.recyclerview.v121
}
//....
material-v190 = { module = "com.google.android.material:material", version.ref = "materialVersion" }
androidx-recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" }
//...
material = "1.12.0"
activity = "1.9.2"
constraintlayout = "2.1.4"
materialVersion = "1.9.0"
recyclerview = "1.3.2"
recyclerviewVersion = "1.2.1"
2.7.2 在 Kotlin 设置 Carousel
在 Activity
中使用 RecyclerView
来显示轮播图。下面的代码展示了如何在 Activity
中初始化 RecyclerView
配置 CarouselSnapHelper
和 CarouselLayoutManager
。
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var carouselAdapter: CarouselAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_carousel)
recyclerView = findViewById(R.id.carousel_recycler_view)
// 初始化 Adapter 设置 RecyclerView
carouselAdapter = CarouselAdapter(getSampleData())
recyclerView.adapter = carouselAdapter
// 使用 CarouselLayoutManager 设置 LayoutManager
recyclerView.layoutManager = CarouselLayoutManager()
val snapHelper = CarouselSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)
}
private fun getSampleData(): List<Int> {
return listOf(
R.drawable.a,
R.drawable.app,
R.drawable.app,
R.drawable.app,
R.drawable.a
)
}
}
轮播图的 RecyclerView
创建一个适配器加载和显示图像,以下是自定义的 CarouselAdapter
。
class CarouselAdapter(private val items: List<Int>) : RecyclerView.Adapter<CarouselAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.carousel_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val imageResId = items[position]
holder.imageView.setImageResource(imageResId)
}
override fun getItemCount(): Int = items.size
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imageView: ImageView = itemView.findViewById(R.id.carousel_image_view)
}
}
2.7.4 测试UI
2.7.5 视频演示
2.8 高级轮播动作的核心代码
代码语言:javascript代码运行次数:0运行复制 override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.imageView.setImageResource(items[position])
// MaskChanged 监听
(holder.itemView as MaskableFrameLayout).setOnMaskChangedListener { maskRect ->
// 当遮罩发生变化时执行动画
holder.itemView.translationX = maskRect.left
holder.itemView.alpha = lerp(1F, 0F, 0F, 80F, maskRect.left)
}
}
2.8.1 视频演示
三、技术难点
3.1 状态管理
在 MDC 中,状态管理相对来说很直接,比如处理图像选择或动态显示状态时,只需简单通过 setImageResource()
等 API 操作。但在 Jetpack Compose 中,使用 remember
和 mutableStateOf
可以更方便管理状态,状态变化会自动重新组合 UI。
3.2 MDC vs Jetpack Compose
- MDC (Material Design Components) 依赖于传统的 Android View 系统,开发只负责需要管理视图、布局和事件处理。这意味着开发需要手动处理视图的更新,例如在 RecyclerView 中,手动调用
notifyDataSetChanged()
刷新界面。 - Jetpack Compose 完全基于声明式 UI编写代码,不需要写XML,UI 的更新和状态绑定,只需改变状态,Compose 会自动重新绘制界面。使用
LazyColumn
和LazyRow
替代RecyclerView
,可以很轻松实现复杂的布局和滚动行为,减少了代码量,提升了开发体验。
3.3 布局和性能
- 在 MDC 中,我们使用
RecyclerView
配合LayoutManager
实现复杂布局,这种方法虽然成熟,但可能需要手动优化滚动性能。 - Jetpack Compose 的
LazyColumn
和LazyRow
提供了内置的性能优化机制,处理长列表时会自动实现惰性加载,不会加载屏幕外的内容,提升性能。
3.4 自定义动画
通过使用 CarouselLayoutManager
,可以轻松实现项目中的轮播效果,通过覆盖 onBindViewHolder
实现复杂的动画和遮罩变化。在 Jetpack Compose 中,实现类似动画效果可以通过 animate*AsState
或 LaunchedEffect
管理 UI 变化。
四、学习笔记
4.1 Jetpack Compose 和 Material Design Components (MDC) 的区别和优势
我可能已经熟悉了 Material Design Components (MDC),这是基于传统的 Android View 系统的 UI 组件库。但近年来,Jetpack Compose 的出现彻底改变了我们构建界面的方式。这两者在开发方式、状态管理、布局处理和性能优化等方面都有明显的区别。我讲解这两者的不同之处,以及在开发中能从它们各自的优势中学到什么。
4.1.1 开发模式:传统 VS 声明式
- MDC:基于传统的 View 系统 MDC 是建立在 Android 的 View 系统之上的,开发界面的时候,你需要写 XML 文件来定义布局,并通过 Java 或 Kotlin 代码来操作这些视图。比如,当你需要更新界面时,你得手动调用
findViewById()
来获取视图,然后通过setText()
或setVisibility()
这样的函数修改界面内容。这种方式是大家熟悉的开发流程,但随着布局变得复杂,代码可能会显得很繁琐。
Jetpack Compose:声明式 UI 开发 不同的是,Jetpack Compose 完全抛弃了 XML 布局,所有 UI 都是用 Kotlin 代码描述的。它采用声明式编程的方式,你只需要专注于描述“界面应该是什么样子”,而不需要手动更新视图。UI 会根据状态的变化自动重新绘制。开发界面很直观,只需要改变状态,Compose 会自动处理 UI 更新。
举个例子,用 Compose 处理按钮点击事件后改变按钮文本,代码如下
代码语言:java复制var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Nim已点击了$count times")
}
在 Compose 中,状态的变化(count++
)直接触发 UI 的更新,而不需要手动去找这个按钮再更新它的文本内容。
4.2 状态管理:谁负责更新 UI?
- MDC:手动更新视图 在 MDC 中,需要自己管理 UI 和数据的同步。比如使用
RecyclerView
,当数据变化时,需要显式调用adapter.notifyDataSetChanged()
刷新列表。这种手动操作会导致代码更加重复且容易出错,特别是在处理复杂状态时。 - Jetpack Compose:自动重新组合 UI Compose 的状态管理很简单。只需要定义一个状态变量,当这个状态变化时,Compose 会自动更新界面。比如使用
remember
和mutableStateOf
跟踪状态,状态发生变化时,Compose 会自动进行重组和更新 UI。 这让代码逻辑很简洁,不需要关注“如何更新 UI”,只需要定义状态“UI 应该是什么样的”。
4.3 布局管理:XML VS Kotlin 代码
- MDC:XML 文件布局 MDC 使用的是传统的 XML 文件布局,像
LinearLayout
、RelativeLayout
等都是通过 XML 定义的。虽然这种方式已经非常成熟,但在处理复杂嵌套布局时,代码容易变得工作量大,而且维护真的很不方便。例如, XML 布局文件:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me" />
</LinearLayout>
Jetpack Compose:用 Kotlin 描述布局 Compose 直接用 Kotlin 代码写布局,比如用 Column
来取代 LinearLayout
,用 Row
排列横向的元素。对于开发来说,这种方式更灵活性,不再需要在 XML 和 Kotlin 之间来回切换。而且,随着项目规模增大,维护也会很容易。
举个简单例子,Compose 中的布局代码:
代码语言:java复制Column {
Text(text = "tv")
Button(onClick = { /* TODO */ }) {
Text(text = "点击 Nim")
}
}
- 这种方式看上去很简洁,少了很多 XML 文件和视图 ID 的管理,布局和逻辑紧密结合在一起。
4.4 性能和可维护性:复杂度表现
- MDC:性能优化需要手动操作 在使用 MDC 时,性能的优化更多地依赖于开发对布局层次的控制,特别是在
RecyclerView
中,需要小心布局的嵌套和重绘问题。虽然 MDC 的性能可以通过手动优化提高,但往往需要编写大量的代码。 - Jetpack Compose:内置性能优化 Compose 则通过惰性布局(如
LazyColumn
、LazyRow
)自动优化性能。它只会渲染屏幕上可见的内容,减少了不必要的计算。再加上它的状态管理机制,减少了手动刷新视图的复杂度,使得开发和维护的成本很低。
4.5 自定义和扩展性:谁更灵活?
- MDC:可定制但代码复杂 MDC 提供了一整套 Material Design 的 UI 组件,你可以通过 XML 或代码来定制这些组件。但对于某些复杂的自定义需求,可能需要继承和扩展已有的
View
或ViewGroup
,这会让代码变得复杂,需要了解较多的 View 生命周期和布局机制。 - Jetpack Compose:灵活易定制 Compose 提供了极高的定制化能力。可以通过自定义
Composable
函数和Modifier
轻松调整布局和样式,扩展性强。例如,可以非常方便组合现有的组件或创建新的组件,而不需要关心视图的生命周期等复杂内容。
4.6 学习成本:MDC VS Jetpack Compose
- MDC:上手门槛低,复杂度高。如果之前有 Android View 开发经验,MDC 的学习曲线会很简单,可以直接复用已有的知识。但随着项目变得复杂,代码量增大,状态管理、UI 更新、性能优化等都会让开发过程变得复杂。
- Jetpack Compose:初期有点陌生,但提升。 如果你习惯了传统的 View 系统,Jetpack Compose 可能一开始会很不习惯,特别是它的声明式 UI 编程风格。但很多练手适应后,你会发现开发效率非常提高。UI 和状态的绑定让开发不再需要手动管理视图更新,代码很简洁清晰,维护成本也非常低。
五、总结
在这篇文章中,展示了如何使用 MDC(Android View)实现一个高级轮播图组件。虽然 MDC 强调了传统的 View 机制,但 Jetpack Compose 的优势在于其声明式编程和自动化的状态管理,适合现代应用开发。通过这两种技术的结合,可以为开发者带来更多选择,帮助我们构建出更加灵活和强大的 UI 界面。
六、思考
个人观点:
Jetpack Compose 和 MDC 是两种不同的开发方式,各有优缺点: MDC 是传统 View 系统,适合那些已经熟悉 Android View 系统的开发者,适合维护现有的老项目或者复杂的 UI 需求。 Jetpack Compose 是 Android UI 开发的未来趋势,简化了 UI 的构建和管理过程,特别是对于新项目来说,它可以非常提升开发效率和代码可维护性。 如果你正在开发新Demo,希望减少手动管理 UI 更新的复杂性,那么 Jetpack Compose 会是一个更好的选择。对于那些依赖旧版框架或者不希望立即切换到新框架的开发者来说,MDC 是一个非常稳定的解决方案。
有任何问题欢迎提问,感谢大家阅读 )
本文标签: MDC和Compose 轮播图的两种实现
版权声明:本文标题:MDC和Compose: 轮播图的两种实现 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1754859072a1707417.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论