前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓软件开发:使用AndroidView(MDC)实现高级轮播图App-下篇

安卓软件开发:使用AndroidView(MDC)实现高级轮播图App-下篇

原创
作者头像
Nimyears
修改2024-10-14 19:27:05
870
修改2024-10-14 19:27:05
举报
文章被收录于专栏:JetpackCompose M3

2024年已经过半了,我作为聋人独立开发者,我经常会时不时反思:自己这半年到底进步了多少?在这篇文章里,我分享一个用 MDC和 Kotlin 语言实现使用AndroidView和Kotlin开发轮播图功能。无论你有没有开发经验,相信这篇文章对你会非常有所帮助。

一、项目背景:

介绍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
复制
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 配置 CarouselSnapHelperCarouselLayoutManager

代码语言:javascript
复制
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

代码语言:javascript
复制
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
复制
 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 中,使用 remembermutableStateOf 可以更方便管理状态,状态变化会自动重新组合 UI。

3.2 MDC vs Jetpack Compose

  • MDC (Material Design Components) 依赖于传统的 Android View 系统,开发只负责需要管理视图、布局和事件处理。这意味着开发需要手动处理视图的更新,例如在 RecyclerView 中,手动调用 notifyDataSetChanged() 刷新界面。
  • Jetpack Compose 完全基于声明式 UI编写代码,不需要写XML,UI 的更新和状态绑定,只需改变状态,Compose 会自动重新绘制界面。使用 LazyColumnLazyRow 替代 RecyclerView,可以很轻松实现复杂的布局和滚动行为,减少了代码量,提升了开发体验。

3.3 布局和性能

  • 在 MDC 中,我们使用 RecyclerView 配合 LayoutManager 实现复杂布局,这种方法虽然成熟,但可能需要手动优化滚动性能。
  • Jetpack Compose 的 LazyColumnLazyRow 提供了内置的性能优化机制,处理长列表时会自动实现惰性加载,不会加载屏幕外的内容,提升性能。
3.4 自定义动画

通过使用 CarouselLayoutManager,可以轻松实现项目中的轮播效果,通过覆盖 onBindViewHolder 实现复杂的动画和遮罩变化。在 Jetpack Compose 中,实现类似动画效果可以通过 animate*AsStateLaunchedEffect 管理 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 会自动更新界面。比如使用 remembermutableStateOf 跟踪状态,状态发生变化时,Compose 会自动进行重组和更新 UI。 这让代码逻辑很简洁,不需要关注“如何更新 UI”,只需要定义状态“UI 应该是什么样的”。

4.3 布局管理:XML VS Kotlin 代码

  • MDC:XML 文件布局 MDC 使用的是传统的 XML 文件布局,像 LinearLayoutRelativeLayout 等都是通过 XML 定义的。虽然这种方式已经非常成熟,但在处理复杂嵌套布局时,代码容易变得工作量大,而且维护真的很不方便。例如, 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 则通过惰性布局(如 LazyColumnLazyRow)自动优化性能。它只会渲染屏幕上可见的内容,减少了不必要的计算。再加上它的状态管理机制,减少了手动刷新视图的复杂度,使得开发和维护的成本很低。

4.5 自定义和扩展性:谁更灵活?

  • MDC:可定制但代码复杂 MDC 提供了一整套 Material Design 的 UI 组件,你可以通过 XML 或代码来定制这些组件。但对于某些复杂的自定义需求,可能需要继承和扩展已有的 ViewViewGroup,这会让代码变得复杂,需要了解较多的 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 是一个非常稳定的解决方案。

有任何问题欢迎提问,感谢大家阅读 )

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、项目背景:
    • 介绍MDC(Android View) Carousel UI
    • 二、项目开发
      • 2.7.1 项目配置
        • 2.7.2 在 Kotlin 设置 Carousel
          • 2.7.4 测试UI
            • 2.7.5 视频演示
              • 2.8 高级轮播动作的核心代码
                • 2.8.1 视频演示
                • 三、技术难点
                  • 3.1 状态管理
                    • 3.2 MDC vs Jetpack Compose
                      • 3.3 布局和性能
                      • 四、学习笔记
                        • 4.1 Jetpack Compose 和 Material Design Components (MDC) 的区别和优势
                          • 4.1.1 开发模式:传统 VS 声明式
                            • 4.2 状态管理:谁负责更新 UI?
                              • 4.3 布局管理:XML VS Kotlin 代码
                                • 4.4 性能和可维护性:复杂度表现
                                  • 4.5 自定义和扩展性:谁更灵活?
                                    • 4.6 学习成本:MDC VS Jetpack Compose
                                    • 五、总结
                                    • 六、思考
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档