9.kotlin安卓实践课程-用kotlin写第一个fragment的recyclerView的adapter具体实现

简介: 简介主要会通过安卓实战来讲解kotlin语法和实际应用,本教程设及知识点包括框架模式mvp+mvvm, Databinding(数据绑定框架),Dagger2(依赖注入框架),DeepLink(页面路由框架),Rxjava,RxAndroid(异步操作框架),Retrofit,Okhtttp等,不过本教程重点在kotlin所以这些框架需要了解可自行百度。

简介

主要会通过安卓实战来讲解kotlin语法和实际应用,本教程设及知识点包括框架模式mvp+mvvm, Databinding(数据绑定框架),Dagger2(依赖注入框架),DeepLink(页面路由框架),Rxjava,RxAndroid(异步操作框架),Retrofit,Okhtttp等,不过本教程重点在kotlin所以这些框架需要了解可自行百度。

针对人群:Android中级以上,kotlin入门


本系列最后一篇我们看看recyclerView的adapter怎么实现的


首先先看一下代码

/**
 * Created by bigman on 18-05-18.
 */
class AndroidAdapter(private val mList: List<AndroidBean>) 
:BaseBindingAdapter<ItemAndroidBinding>() {
  override fun getItemCount(): Int {
    return mList.size
  }

  override fun onBindViewHolder(holder: DataBoundViewHolder<ItemAndroidBinding>, position: Int) {
    super.onBindViewHolder(holder, position)
    //数据绑定
    holder.binding.androidbean = mList[position]
    //数据立即绑定而不是在下一帧的时候才绑定,避免闪烁和数据错乱
    holder.binding.executePendingBindings()
  }

  override fun onCreateViewHolder(parent: ViewGroup,
      viewType: Int): DataBoundViewHolder<ItemAndroidBinding> {
    return DataBoundViewHolder(
            ItemAndroidBinding.inflate(LayoutInflater.from(parent.context), parent, false))
  }
}

首先看主构造函数和继承

class AndroidAdapter(private val mList: List<AndroidBean>) 
:BaseBindingAdapter<ItemAndroidBinding>() 
  1. 主构造函数传入一个List<AndroidBean>类型的mList只读变量
  2. 继承至BaseBindingAdapter<ItemAndroidBinding>()

下一步我们看一下基类BaseBindingAdapter的具体实现

/**
 * Created by bigman on 18-05-18.
 */
abstract class BaseBindingAdapter<B : ViewDataBinding>
 : RecyclerView.Adapter<DataBoundViewHolder<B>>() {
    var mListener: ((pos: Int) -> Unit)? = null

    override fun onBindViewHolder(holder: DataBoundViewHolder<B>, position: Int) {
        holder.binding.root.setOnClickListener {
            mListener?.invoke(holder.adapterPosition)
        }
    }

    fun setOnItemClickListener(listener: ((pos: Int) -> Unit)) {
        mListener = listener
    }

}
  • 大家可以看到BaseBindingAdapter需要传入ViewDataBinding类型,这个ViewDataBinding是databinding里面所有视图bingding类的基类,
  • 然后毫无疑问它必须继承于RecyclerView.Adapter<DataBoundViewHolder<B>>,这个我们平时写java的RecyclerView.Adapter的时候都需要继承的
    这里还有一个DataBoundViewHolder<B>,看一下代码实现
/**
 * Created by bigman on 18-05-18.
 */
 class DataBoundViewHolder<T : ViewDataBinding>(val binding:T) 
: RecyclerView.ViewHolder(binding.root) {
}

其实它就是一个RecyclerView.ViewHolder,只是这里我们传入了通用的ViewDataBinding使它变成可以绑定任意视图

回到BaseBindingAdapter,这个基类主要功能就是实现一个通用的databinding用的适配器,只要传入databinding视图类型即可,类内部提供了一个点击事件的回调方法

然后再回到AndroidAdapter
这里主要由三个方法,

  • getItemCount ()返回绑定列表长度,
  • onBindViewHolder ()实现视图数据绑定,这里用的databingding的数据绑定,holder.binding.executePendingBindings(),这句代码比较重要不加可能导致数据错乱或者页面闪烁
  • onCreateViewHolder()主要是完成databinding的holder构建
 override fun onCreateViewHolder(parent: ViewGroup,
      viewType: Int): DataBoundViewHolder<ItemAndroidBinding> {
    return DataBoundViewHolder(
            ItemAndroidBinding.inflate(LayoutInflater.from(parent.context), parent, false))
  }

这里的 ItemAndroidBinding是databinding根据我们的布局文件自动生成的,我们看一下我们这个列表条目布局代码,名称item_android.xml注意对比databinding生成的binding类名称

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <import type="android.view.View" />

        <variable
            name="androidbean"
            type="com.bigman.kotlin.bean.AndroidBean" />
    </data>

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_marginLeft="2dp"
        android:layout_marginRight="2dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:background="#fff"
        android:orientation="vertical"
        app:cardCornerRadius="5dp"
        android:paddingTop="10dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="vertical"
            android:paddingLeft="16dp"
            android:paddingBottom="10dp"

            android:paddingRight="16dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{androidbean.desc}"
                android:textColor="#000"
                android:textSize="16sp" />

            <ImageView

                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_marginTop="10dp"
                android:scaleType="center"
                android:visibility="@{androidbean.hasImg()?View.VISIBLE:View.GONE}"
                app:load_image="@{androidbean.images[0]}" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <TextView
                    android:layout_marginTop="10dp"
                    android:text="@{androidbean.who}"
                    android:layout_weight="1"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    />

                <TextView
                    android:layout_marginTop="10dp"
                    android:text = "@{androidbean.create()}"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    />

            </LinearLayout>
        </LinearLayout>

    </android.support.v7.widget.CardView>
</layout>

具体代码和前面说过的布局没啥太大区别,主要就是data数据的传入和数据绑定

眼神比较犀利的同学可能会看到几个比较不一样的地方而存在疑惑,我们看看是哪里

 <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_marginTop="10dp"
                android:scaleType="center"
                android:visibility="@{androidbean.hasImg()?View.VISIBLE:View.GONE}"
                app:load_image="@{androidbean.images[0]}" />

这里的app:load_image这是''databinding允许的一个函数绑定形式
我们看一下具体实现:

/**
 * Created by bigman on 18-05-18.
 */

@BindingAdapter("load_image")
fun loadImage(imageView: ImageView, url: String?) =
        Glide.with(imageView.context).load(url)
                .crossFade()
                .into(imageView)

@BindingAdapter("set_text")
fun setText(textView: TextView, string: String) {
    textView.setText("bigman" + string)
}


@BindingAdapter("load_asset")
fun loadAsset(imageView: ImageView, id: Int) =
        Glide.with(imageView.context).load(id).into(imageView)

这几个函数被我卸载随意的一个kt文件里面,然后通过 @BindingAdapter注解,我们的databinding框架就能很容易的找到它

那么我们这一系列kotlin 安卓实战内容到这里结束了,虽然kotlin知识点讲的不错,但是基本的运用知道这些也差不多够了,大家可以自己动手写一下,本系列主要目的已经达到,就是kotlin在这种mvp+mvvm目前最合理框架上的具体应用


欢迎一起交流,有问题加群交流

kotlin实战交流群群二维码.png
相关文章
|
16天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
17天前
|
数据库 Android开发 开发者
构建高效Android应用:Kotlin协程的实践指南
【4月更文挑战第2天】随着移动应用开发的不断进步,开发者们寻求更流畅、高效的用户体验。在Android平台上,Kotlin语言凭借其简洁性和功能性赢得了开发社区的广泛支持。特别是Kotlin协程,作为一种轻量级的并发处理方案,使得异步编程变得更加简单和直观。本文将深入探讨Kotlin协程的核心概念、使用场景以及如何将其应用于Android开发中,以提高应用性能和响应能力。通过实际案例分析,我们将展示协程如何简化复杂任务,优化资源管理,并为最终用户提供更加流畅的体验。
|
26天前
|
调度 数据库 Android开发
构建高效Android应用:Kotlin协程的实践与优化
在Android开发领域,Kotlin以其简洁的语法和平台友好性成为了开发的首选语言。其中,Kotlin协程作为处理异步任务的强大工具,它通过提供轻量级的线程管理机制,使得开发者能够在不阻塞主线程的情况下执行后台任务,从而提升应用性能和用户体验。本文将深入探讨Kotlin协程的核心概念,并通过实例演示如何在实际的Android应用中有效地使用协程进行网络请求、数据库操作以及UI的流畅更新。同时,我们还将讨论协程的调试技巧和常见问题的解决方法,以帮助开发者避免常见的陷阱,构建更加健壮和高效的Android应用。
35 4
|
18天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践与优化
在响应式编程范式日益盛行的今天,Kotlin协程作为一种轻量级的线程管理解决方案,为Android开发带来了性能和效率的双重提升。本文旨在探讨Kotlin协程的核心概念、实践方法及其在Android应用中的优化策略,帮助开发者构建更加流畅和高效的应用程序。通过深入分析协程的原理与应用场景,结合实际案例,本文将指导读者如何优雅地解决异步任务处理,避免阻塞UI线程,从而优化用户体验。
|
23天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
在开发高性能的Android应用时,选择合适的编程语言至关重要。近年来,Kotlin因其简洁性和功能性受到开发者的青睐,但其性能是否与传统的Java相比有所不足?本文通过对比分析Kotlin与Java在Android平台上的运行效率,揭示二者在编译速度、运行时性能及资源消耗方面的具体差异,并探讨在实际项目中如何做出最佳选择。
17 4
|
1天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
5 0
|
6天前
|
Java Android开发 C++
Kotlin vs Java:选择最佳语言进行安卓开发
【4月更文挑战第13天】Java曾是安卓开发的主流语言,但Kotlin的崛起改变了这一局面。Google在2017年支持Kotlin,引发两者优劣讨论。Java以其成熟稳定、强大生态和跨平台能力占优,但代码冗长、开发效率低和语言特性过时是短板。Kotlin则以简洁语法、空安全设计和高度兼容Java脱颖而出,但社区和生态系统仍在发展中,可能存在学习曲线和性能问题。选择语言应考虑项目需求、团队熟悉度、维护性、性能和生态系统。无论选择哪种,理解其差异并适应新技术至关重要。
|
12天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。
|
26天前
|
移动开发 Android开发 开发者
构建高效Android应用:探究Kotlin协程的优势
在移动开发领域,尤其是针对Android平台,性能优化和流畅的用户体验始终是开发者追求的核心目标。近年来,Kotlin语言凭借其简洁性和功能性成为Android开发的新宠,特别是Kotlin协程的引入,为编写异步代码提供了一种全新的范式。本文将深入探讨Kotlin协程在Android应用开发中的应用及其带来的优势,旨在帮助开发者理解并运用协程来提高应用的性能和响应性。
|
28天前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【2月更文挑战第31天】 在移动开发领域,性能优化和流畅的用户体验一直是开发者追求的目标。随着Kotlin语言的流行,其异步编程解决方案——协程(Coroutines),为Android应用带来了革命性的并发处理能力。本文将深入探讨Kotlin协程的核心概念、设计原理以及在Android应用中的实际应用案例,旨在帮助开发者掌握这一强大的工具,从而提升应用的性能和响应能力。