BindingAdp (databinding+recyclerview adapter)

6398 단어

장점


코드가 적고, 단지 하나의 종류일 뿐, 기능은 간소화될 뿐, 더 많은 기능이 필요하고, 스스로 확장해야 한다
데이터가 귀속되면 데이터 변화가 자동으로 갱신되며 수동으로 갱신할 필요가 없습니다(addOnListChangedCallback)

사용법

class Adp : BindingAdp(R.layout.item) {
        override fun bindData(binding: ItemBinding, data: Bean) {
            binding.bean = data
        }
    }
adp.addHeaderView(headerBinding.root)//   view
adp.setData(list)//     ,    

주 ItemBinding은 데이터 binding 아래의 item 레이아웃이고 Bean은 모델이며 bindData에서 수동으로 item에 모델을 설정합니다

BindingAdp.kt

package wine.ls.com.databinding

import android.databinding.DataBindingUtil
import android.databinding.ObservableArrayList
import android.databinding.ObservableList
import android.databinding.ViewDataBinding
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.support.v7.widget.StaggeredGridLayoutManager
import android.support.v7.widget.GridLayoutManager


abstract class LBindingAdp(private val layoutRes: Int) : RecyclerView.Adapter() {
    private val hanlder = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message?) {
            super.handleMessage(msg)
            when (msg!!.what) {
                1 -> notifyDataSetChanged()
                2 -> {
                    val strs = msg.obj.toString().split(",")
                    notifyItemRangeChanged(strs[0].toInt(), strs[1].toInt())
                }
                3 -> {
                    val strs = msg.obj.toString().split(",")
                    notifyItemRangeInserted(strs[0].toInt(), strs[1].toInt())
                }
                4 -> {
                    val strs = msg.obj.toString().split(",")
                    notifyItemRangeRemoved(strs[0].toInt(), strs[2].toInt())
                    notifyItemRangeInserted(strs[1].toInt(), strs[2].toInt())
                }
                5 -> {
                    val strs = msg.obj.toString().split(",")
                    notifyItemRangeRemoved(strs[0].toInt(), strs[1].toInt())
                }
            }
        }
    }
    private var list: ObservableArrayList? = null
    private val HEAD = 1111
    private val NORMAL = 2222
    private var headView: View? = null

    fun addHeaderView(view: View) {
        headView = view
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LBindingVH {
        return if (viewType == HEAD) {
            LBindingVH(headView!!)
        } else {
            LBindingVH(LayoutInflater.from(parent.context).inflate(layoutRes, parent, false))
        }
    }

    fun setData(lis: ObservableArrayList) {
        this.list = lis
        this.list!!.addOnListChangedCallback(callback)
    }

    private var callback: ObservableList.OnListChangedCallback> = object : ObservableList.OnListChangedCallback>() {
        override fun onChanged(sender: ObservableList) {
            hanlder.sendEmptyMessage(1)
        }

        override fun onItemRangeChanged(sender: ObservableList, positionStart: Int, itemCount: Int) {
            val msg = Message()
            msg.what = 2
            msg.obj = "$positionStart,$itemCount"
            hanlder.sendMessage(msg)
        }

        override fun onItemRangeInserted(sender: ObservableList, positionStart: Int, itemCount: Int) {
            val msg = Message()
            msg.what = 3
            msg.obj = "$positionStart,$itemCount"
            hanlder.sendMessage(msg)
        }

        override fun onItemRangeMoved(sender: ObservableList, fromPosition: Int, toPosition: Int, itemCount: Int) {
            val msg = Message()
            msg.what = 4
            msg.obj = "$fromPosition,$toPosition,$itemCount"
            hanlder.sendMessage(msg)
        }

        override fun onItemRangeRemoved(sender: ObservableList, positionStart: Int, itemCount: Int) {
            val msg = Message()
            msg.what = 5
            msg.obj = "$positionStart,$itemCount"
            hanlder.sendMessage(msg)
        }
    }

    override fun getItemCount() = if (headView != null) list!!.size + 1 else list!!.size
    override fun onBindViewHolder(holder: LBindingVH, position: Int) {
        if (null == headView) {
            val binding = DataBindingUtil.getBinding(holder.itemView) as T
            bindData(binding, list!![position])
            binding.executePendingBindings()
        } else {
            if (position > 0) {
                val binding = DataBindingUtil.getBinding(holder.itemView) as T
                bindData(binding, list!![position - 1])
                binding.executePendingBindings()
            }
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        val manager = recyclerView.layoutManager
        if (manager is GridLayoutManager) {
            manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                override fun getSpanSize(position: Int): Int {
                    return if (getItemViewType(position) == HEAD)
                        manager.spanCount
                    else
                        1
                }
            }
        }
    }

    override fun onViewAttachedToWindow(holder: LBindingVH) {
        super.onViewAttachedToWindow(holder)
        val lp = holder.itemView.layoutParams
        if (lp != null && lp is StaggeredGridLayoutManager.LayoutParams) {
            lp.isFullSpan = holder.layoutPosition == 0
        }
    }

    abstract fun bindData(binding: T, data: D)

    override fun getItemViewType(position: Int): Int {
        return if (headView != null && position == 0) {
            HEAD
        } else {
            NORMAL
        }
    }

    class LBindingVH(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val binding: ViewDataBinding? = DataBindingUtil.bind(itemView)
    }
}


좋은 웹페이지 즐겨찾기