委托适配器不会重用ViewHolders

时间:2018-09-10 13:24:07

标签: android android-recyclerview recycler-adapter

我想在回收者视图中显示不同类型的项目,因此我使用委托。但是我的问题是我的适配器无法重用旧的ViewHolders。对于每个项目,每次都在onCreateViewHolder上触发并创建新项目。需要很长时间。在真实设备上仅需花费1-3秒的时间即可完成400个项目。滞后3秒的计数不是很多。 我该如何解决?

代码:

class ExpandableAdapter(simpleList: List<Any>) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), ExistFinesDelegateAdapter.onDocumentClicked{

    lateinit var context: Context
    private var delegateAdapters = SparseArrayCompat<ViewTypeDelegateAdapter>()
    private var list: MutableList<Any> = mutableListOf()
    private var mutableList: MutableList<Any> = mutableListOf()
    private val collapseState = 1L
    private val expandState = 0L

    var onItemClick: ((FinesInfoResult, poisiton: Int) -> Unit)? = null
    var onCollapsedDoc: ((FinesInfoResult) -> Unit)? = null
    private var expandedItemPosition: Int? = null

    companion object {
        val PARENT_NO_FINES = 1
        val PARENT_FINES_EXIST = 2
        val PARENT_LOADING = 3
        val PARENT_ERROR_NETWORK = 4
        val PARENT_ERROR_UNKNOWN = 5
        val CHILD = 6
    }

    init {
        Log.d("tag", "init adapter")
        Log.d("tag", "time - ${ System.currentTimeMillis()}")

        delegateAdapters.put(PARENT_FINES_EXIST, ExistFinesDelegateAdapter(this))
        delegateAdapters.put(PARENT_NO_FINES, NoFinesDelegateAdapter())
        delegateAdapters.put(PARENT_LOADING, LoadingDelegateAdapter())
        delegateAdapters.put(PARENT_ERROR_NETWORK, ErrorDelegateAdapter())
        delegateAdapters.put(PARENT_ERROR_UNKNOWN, ErrorDelegateAdapter())
        delegateAdapters.put(CHILD, ChildDelegateAdapter())

        list  = simpleList.toMutableList()
        //first expand
        var position = 0
        for (item in simpleList){
            if (item is FinesInfoResult){
                if ( item.doc.collapsed == expandState){
                    var childList = item.fines
                    list.addAll(position + 1, childList!!)
                    position += childList.size
                }
            }
            position++
        }
        mutableList = list
        notifyDataSetChanged()
        Log.d("tag", "init adapter notifyDataSetChanged")
        Log.d("tag", "time - ${ System.currentTimeMillis()}")
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        Log.d("tag", "onCreateViewHolder")
        Log.d("tag", "time - ${ System.currentTimeMillis()}")
        return delegateAdapters.get(viewType).onCreateViewHolder(parent, viewType)
    }

    override fun onExpandOrCollapse(position: Int) {
        expandOrCollapseGroup(position)
    }

    override fun oItemClicked(position: Int) {
        onItemClick?.invoke(mutableList[position] as FinesInfoResult, position)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        Log.d("tag", "onBindViewHolder")
        Log.d("tag", "time - ${ System.currentTimeMillis()}")
        val item = list[position]
        delegateAdapters.get(getItemViewType(position)).onBindViewHolder(holder, item)
    }


    override fun getItemCount(): Int {
        return mutableList.size
    }

    override fun getItemViewType(position: Int): Int {
        val item = mutableList[position]
        if( item is FinesInfoResult) {
            if (item.doc.finesCount > 0){
                return PARENT_FINES_EXIST
            } else if (item.doc.finesCount == 0L) {
                return PARENT_NO_FINES
            } else if (item.doc.lastUpdateTime == null) {
                return PARENT_LOADING
            } else {
                return PARENT_ERROR_NETWORK
            }
        } else {
            return CHILD
        }
    }


    fun addFinesToDoc(docData: FinesInfoResult, position: Int){
        mutableList.removeAt(position)
        mutableList.add(position, docData)
        if (docData.fines != null){
            expandOrCollapseGroup(position)
        }
    }

    private fun expandOrCollapseGroup(position: Int){
        val item = mutableList[position] as FinesInfoResult
        if (item.doc.collapsed == expandState){ //collapse
            item.doc.collapsed = collapseState
            val fines = item.fines
            for (child in fines!!){
                mutableList.remove(child)
            }
            notifyDataSetChanged()
        } else { //expand
            item.doc.collapsed = expandState
            val childList = item.fines
            mutableList.addAll(position + 1, childList!!)
            notifyDataSetChanged()
        }
        onCollapsedDoc?.invoke(item)
    }

}

0 个答案:

没有答案