2024年已经过半了,我作为聋人独立开发者,我经常会时不时反思:自己这半年到底进步了多少?在这篇文章里,我分享一个用 MDC和 Kotlin 语言实现使用AndroidView和Kotlin开发轮播图功能。无论你有没有开发经验,相信这篇文章对你会非常有所帮助。
Material Design Components (MDC) 是构建现代 Android 应用的 UI 组件库,遵循 Google 的 Material Design 规范。而轮播图(Carousel)是现代 UI 中常见的功能之一,展示图片、商品列表等内容时非常有用。
参考资料:Material Design Components for Android 1.9.0 - Material Design
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"
在 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)
}
}
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)
}
}
在 MDC 中,状态管理相对来说很直接,比如处理图像选择或动态显示状态时,只需简单通过 setImageResource()
等 API 操作。但在 Jetpack Compose 中,使用 remember
和 mutableStateOf
可以更方便管理状态,状态变化会自动重新组合 UI。
notifyDataSetChanged()
刷新界面。LazyColumn
和 LazyRow
替代 RecyclerView
,可以很轻松实现复杂的布局和滚动行为,减少了代码量,提升了开发体验。RecyclerView
配合 LayoutManager
实现复杂布局,这种方法虽然成熟,但可能需要手动优化滚动性能。LazyColumn
和 LazyRow
提供了内置的性能优化机制,处理长列表时会自动实现惰性加载,不会加载屏幕外的内容,提升性能。通过使用 CarouselLayoutManager
,可以轻松实现项目中的轮播效果,通过覆盖 onBindViewHolder
实现复杂的动画和遮罩变化。在 Jetpack Compose 中,实现类似动画效果可以通过 animate*AsState
或 LaunchedEffect
管理 UI 变化。
我可能已经熟悉了 Material Design Components (MDC),这是基于传统的 Android View 系统的 UI 组件库。但近年来,Jetpack Compose 的出现彻底改变了我们构建界面的方式。这两者在开发方式、状态管理、布局处理和性能优化等方面都有明显的区别。我讲解这两者的不同之处,以及在开发中能从它们各自的优势中学到什么。
findViewById()
来获取视图,然后通过 setText()
或 setVisibility()
这样的函数修改界面内容。这种方式是大家熟悉的开发流程,但随着布局变得复杂,代码可能会显得很繁琐。Jetpack Compose:声明式 UI 开发 不同的是,Jetpack Compose 完全抛弃了 XML 布局,所有 UI 都是用 Kotlin 代码描述的。它采用声明式编程的方式,你只需要专注于描述“界面应该是什么样子”,而不需要手动更新视图。UI 会根据状态的变化自动重新绘制。开发界面很直观,只需要改变状态,Compose 会自动处理 UI 更新。
举个例子,用 Compose 处理按钮点击事件后改变按钮文本,代码如下
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Nim已点击了$count times")
}
在 Compose 中,状态的变化(count++
)直接触发 UI 的更新,而不需要手动去找这个按钮再更新它的文本内容。
RecyclerView
,当数据变化时,需要显式调用 adapter.notifyDataSetChanged()
刷新列表。这种手动操作会导致代码更加重复且容易出错,特别是在处理复杂状态时。remember
和 mutableStateOf
跟踪状态,状态发生变化时,Compose 会自动进行重组和更新 UI。
这让代码逻辑很简洁,不需要关注“如何更新 UI”,只需要定义状态“UI 应该是什么样的”。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 中的布局代码:
Column {
Text(text = "tv")
Button(onClick = { /* TODO */ }) {
Text(text = "点击 Nim")
}
}
RecyclerView
中,需要小心布局的嵌套和重绘问题。虽然 MDC 的性能可以通过手动优化提高,但往往需要编写大量的代码。LazyColumn
、LazyRow
)自动优化性能。它只会渲染屏幕上可见的内容,减少了不必要的计算。再加上它的状态管理机制,减少了手动刷新视图的复杂度,使得开发和维护的成本很低。View
或 ViewGroup
,这会让代码变得复杂,需要了解较多的 View 生命周期和布局机制。Composable
函数和 Modifier
轻松调整布局和样式,扩展性强。例如,可以非常方便组合现有的组件或创建新的组件,而不需要关心视图的生命周期等复杂内容。在这篇文章中,展示了如何使用 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 是一个非常稳定的解决方案。
有任何问题欢迎提问,感谢大家阅读 )
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。