werbhelius / MoreType

new method to build data in RecyclerView with Kotlin!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

与 MultiType 的异同

appdev opened this issue · comments

这个和MultiType有什么区别呢?

commented

@huclengyue
核心**是一样的【数据驱动视图】,区别在实现和使用上

1. 我们最终是要形成一种数据与视图的对应关系,即 MoreType 的 data 和 viewType。

  • MultiType 在当时我看的时候,是使用 list 实现,通过相同的 index 形成一个对应关系。
  • MoerType 采用 SparseArrayCompat 实现,通过在 viewType 中返回的 layout 作为 key 来确定对应关系,在 Android 中布局是唯一的,也可以说一种布局代表一种视图。

2. 更简单的实现视图

只需要继承 MoerViewType<T: Any>() 并重写三个方法,这三个方法的目的也很明确

  • getViewLayout() : 返回视图的布局,当成唯一的 key 来和 data 确定关系,同时用于创建 ViewHolder
  • getViewModel() : 返回视图对应的数据类(data),即声明视图所对应的数据类
  • bindData () : 绑定数据,处理各种事件,内置点击事件实现方法

可以看到,我们并不用去重复写 ViewHolder,如果配合 kotlin-android-extensionsfindViewId 也省去了,下面是实现简单的聊天界面的 viewType 代码,非常简洁,相信了解 kotlin 的语法的话不需要任何注释你也可以看得懂

class MessageInViewType : MoreViewType<Message>() {

    override fun getViewLayout(): Int = R.layout.item_view_multi_message_in

    override fun getViewModel(): KClass<Message> = Message::class

    override fun bindData(data: Message, holder: MoreViewHolder) {

        holder.itemView.message_icon.setImageURI(data.icon)
        if (data.showTime) {
            holder.itemView.message_time.visibility = View.VISIBLE
            holder.itemView.message_time.text = Utils.sendTime(data.time.toLong() * 1000)
        } else {
            holder.itemView.message_time.visibility = View.INVISIBLE
        }
        holder.itemView.message_content_layout.removeAllViews()
        var currentLayout: RelativeLayout? = null
        when (data.messageType) {
            "text" -> {
                currentLayout = LayoutInflater.from(holder.itemView.context).inflate(R.layout.widget_view_message_in_text, holder.itemView.message_content_layout, false) as RelativeLayout
                val text = currentLayout.findViewById<AppCompatTextView>(R.id.message_in_text)
                text.text = data.text
            }
            "image" -> {
                currentLayout = LayoutInflater.from(holder.itemView.context).inflate(R.layout.widget_view_message_in_image, holder.itemView.message_content_layout, false) as RelativeLayout
                val image = currentLayout.findViewById<SimpleDraweeView>(R.id.message_in_image)
                image.setImageURI(data.url)
                setImgSize(data.width, data.height, image)
            }
            else -> {

            }
        }
        holder.itemView.message_content_layout.addView(currentLayout)
    }

    fun setImgSize(width: String, height: String, image: SimpleDraweeView) {
        val size = Utils.getIMImageSize(width.toDouble(), height.toDouble())
        val lp = image.layoutParams
        lp.width = size.width
        lp.height = size.height
        image.layoutParams = lp
    }
}

3. adapter 链式使用

先看一个完整的使用例子

adapter.userSoleRegister()
                .register(TitleViewType())
                .register(CompleteViewType())
                .register(HorizontalViewType())
                .multiRegister(Message::class, object : MultiLink<Message> {
                    override fun link(data: Message): MoreViewType<Message>? {
                        if (data.me) {
                            return MessageOutViewType()
                        } else {
                            return MessageInViewType()
                        }
                    }
                })
                .renderWithAnimation()
                .startAnimPosition(1)
                .attachTo(complete_list)
  • 默认 data <-> viewType 一对一关系的,我们不需要在注册的时候声明 data 数据类,因为在 ViewType 中已经确定了数据类型,不用重复声明
  • 类似 im 界面, data <-> viewType 一对多关系的,我们使用 multiRegister 完成,需要显式声明 data,实现 MultiLink 接口来做判断,这些操作都是在一个方法中完成
  • 提供列表显示动画,并支持自定义
  • 支持全局注册
  • 全部都是链式调用,非常直观

4. 强大的 Kotlin

这个应该是最大的不同的, kotlin 真的是一门写起来让人很爽的语言,得益于 Kotlin ,MoreType 可以更加自如的操作数据,内置了以下一些方法:

  • fun loadData(data: Any) :加载数据 object/list
  • fun getData(position: Int) : Any :获取某一个数据
  • fun removeAllData() :移除全部数据
  • fun removeData(data: Any) :移除某一条数据
  • fun removeData(position: Int) :根据 position 移除某一条数据

通过这些方法,可以更方便快速的操作数据,完成下拉刷新,上滑加载等功能,可以参考这里的实现CompleteActivity.kt

开始你会发现很像,确实 MultiType 的思路在我看来是目前有关组合布局显示上实践最好的,当然如果你去查大量源码,你会发现很多库都是这个思路,并不是 MultiType 独创,好的技术当然值得学习。

MoreType 的目的是为了更简洁的方便人们使用,当你看完 sample 中的示例代码,你会发现唯一的不同就是处处不同

😄