从API检索和更新数据时,保留可扩展recyclerview的布局

时间:2019-06-17 10:52:16

标签: android kotlin android-recyclerview recyclerview-layout

我目前拥有一个功能全面的可扩展RecyclerView(具有两个不同的视图:一个用于标题,另一个用于每个标题的内容)。标题下的每张卡的内容都是通过API调用检索到我的后端的。

今天,我设法实现了滑动以刷新功能,但是问题是当我执行刷新时,所有组都崩溃了。从UI / UX角度来看,这不是很吸引人,并为用户增加了额外的步骤。因此,我正在寻找一种执行刷卡刷新而不使组崩溃的方法(即卡的内容已更新,但卡与调用刷新时的位置相同)。我已经看过使用herehere的答案中详细介绍的onSaveInstanceStateonRestoreInstanceState,但无济于事。

我的适配器代码如下:

class BusStopsServicesArrivalRVAdapter :
    RecyclerView.Adapter<RecyclerView.ViewHolder>(), BusStopNoSectionHeaderViewHolder.HeaderViewHolderCallback {
    private val SERVICE_TYPE = 1
    private val STOP_TYPE = 2
    private var busStopServiceList: ArrayList<BusStopService>? = null
    private var busStopList: ArrayList<String>? = null

    private var busArrivalViewTypes: SparseArray<BusArrivalViewType>? = null
    private var headerExpandTracker: SparseIntArray? = null

    lateinit var context: Context

    var nineOneCount = 0
    var threeOneCount = 0
    var threeNineCount = 0
    var fiveNineCount = 0

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val view: View
        when (viewType) {
            SERVICE_TYPE -> {
                view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.card_bus_stop_service, parent, false)
                return BusStopServiceHolder(view)
            }
            STOP_TYPE -> {
                view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.card_bus_stop_section, parent, false)
                return BusStopNoSectionHeaderViewHolder(view, this)
            }
            else -> {
                view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.card_bus_stop_service, parent, false)
                return BusStopServiceHolder(view)
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val itemViewType = getItemViewType(position)
        val viewType = busArrivalViewTypes!!.get(position)
        if (itemViewType == SERVICE_TYPE) {
            bindBusStopServiceViewHolder(holder, viewType)
        } else {
            bindHeaderViewHolder(holder, position, viewType)
        }
    }

    private fun bindHeaderViewHolder(holder: RecyclerView.ViewHolder, position: Int, busArrivalViewType: BusArrivalViewType) {
        val dataIndex = busArrivalViewType.dataIndex
        val headerViewHolder = holder as BusStopNoSectionHeaderViewHolder
        when(busStopList!![dataIndex]) {
            "D" -> {
                headerViewHolder.busStopNoTextView.text =
                    context.resources.getString(R.string.bus_stop_services_description_D)
            }

            "C" -> {
                headerViewHolder.busStopNoTextView.text =
                    context.resources.getString(R.string.bus_stop_services_description_C)
            }

            "B" -> {
                headerViewHolder.busStopNoTextView.text =
                    context.resources.getString(R.string.bus_stop_services_description_B)
            }

            "A" -> {
                headerViewHolder.busStopNoTextView.text =
                    context.resources.getString(R.string.bus_stop_services_description_A)
            }
        }
        // headerViewHolder.busStopNoTextView.text = busStopList!![dataIndex]
        if (isExpanded(position)) {
            headerViewHolder.busStopNoTextView
                .setCompoundDrawablesWithIntrinsicBounds(null, null, headerViewHolder.arrowUp, null)
        } else {
            headerViewHolder.busStopNoTextView
                .setCompoundDrawablesWithIntrinsicBounds(null, null, headerViewHolder.arrowDown, null)
        }
    }

    private fun bindBusStopServiceViewHolder(holder: RecyclerView.ViewHolder, busArrivalViewType: BusArrivalViewType) {
        val dataIndex = busArrivalViewType.dataIndex
        (holder as BusStopServiceHolder).bindData(busStopServiceList!![dataIndex], context)
    }

    override fun getItemCount(): Int {
        var count = 0
        if (busStopList != null && busStopServiceList != null) {
            busArrivalViewTypes!!.clear()
            var collapsedCount = 0
            for (i in busStopList!!.indices) {
                busArrivalViewTypes!!.put(count, BusArrivalViewType(i, STOP_TYPE))
                count += 1
                val userType = busStopList!![i]
                val childCount = getChildCount(userType)
                if (headerExpandTracker!!.get(i) != 0) {
                    // Expanded State
                    for (j in 0 until childCount) {
                        busArrivalViewTypes!!.put(count, BusArrivalViewType(count - (i + 1) + collapsedCount, SERVICE_TYPE))
                        count += 1
                    }
                } else {
                    // Collapsed
                    collapsedCount += childCount
                }
            }
        }
        return count
    }

    override fun getItemViewType(position: Int): Int {
        return if (busArrivalViewTypes!!.get(position).type === STOP_TYPE) {
            STOP_TYPE
        } else {
            SERVICE_TYPE
        }
    }

    private fun getChildCount(type: String): Int {
        when (type) {
            "D" -> return nineOneCount
            "C" -> return threeOneCount
            "B" -> return threeNineCount
            "A" -> return fiveNineCount
            else -> return 0
        }
    }

    fun setUserListAndType(busStopServiceList: ArrayList<BusStopService>?, busStopNoList: ArrayList<String>?, c: Context) {
        if (busStopServiceList != null && busStopNoList != null) {
            this.busStopServiceList = busStopServiceList
            this.busStopList = busStopNoList
            this.context = c
            busArrivalViewTypes = SparseArray<BusArrivalViewType>(busStopServiceList.size + busStopNoList.size)
            headerExpandTracker = SparseIntArray(busStopNoList.size)
            notifyDataSetChanged()

            for (i in busStopServiceList.indices) {
                when(busStopServiceList[i].busStopCode) {
                    "D" -> {
                        nineOneCount += 1
                    }

                    "C" -> {
                        threeOneCount += 1
                    }

                    "B" -> {
                        threeNineCount += 1
                    }

                    "A" -> {
                        fiveNineCount += 1
                    }
                }
            }


        }
    }

    override fun onHeaderClick(position: Int) {
        val viewType = busArrivalViewTypes!!.get(position)
        val dataIndex = viewType.dataIndex
        val userType = busStopList!![dataIndex]
        val childCount = getChildCount(userType)
        if (headerExpandTracker!!.get(dataIndex) == 0) {
            headerExpandTracker!!.put(dataIndex, 1)
            notifyItemRangeInserted(position + 1, childCount)
        } else {
            headerExpandTracker!!.put(dataIndex, 0)
            notifyItemRangeRemoved(position + 1, childCount)
        }
    }

    override fun isExpanded(position: Int): Boolean {
        val dataIndex = busArrivalViewTypes!!.get(position).dataIndex
        return headerExpandTracker!!.get(dataIndex) == 1
    }

}

0 个答案:

没有答案