1 /** 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package com.android.healthconnect.controller.shared.recyclerview 15 16 import android.view.View 17 import android.view.ViewGroup 18 import androidx.recyclerview.widget.RecyclerView 19 20 /** 21 * {@link RecyclerView.Adapter} that handles binding objects of different classes to a corresponding 22 * {@link View}. 23 */ 24 class RecyclerViewAdapter 25 private constructor( 26 private val itemClassToItemViewTypeMap: Map<Class<*>, Int>, 27 private val itemViewTypeToViewBinderMap: Map<Int, ViewBinder<*, out View>> 28 ) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() { 29 30 class Builder { 31 companion object { 32 // Base item view type to use when setting a view binder for objects of a specific class 33 private const val BASE_ITEM_VIEW_TYPE = 100 34 } 35 36 private var nextItemType = BASE_ITEM_VIEW_TYPE 37 private val itemClassToItemViewTypeMap: MutableMap<Class<*>, Int> = mutableMapOf() 38 private val itemViewTypeToViewBinderMap: MutableMap<Int, ViewBinder<*, out View>> = 39 mutableMapOf() 40 setViewBindernull41 fun <T> setViewBinder(clazz: Class<T>, viewBinder: ViewBinder<T, out View>): Builder { 42 itemClassToItemViewTypeMap[clazz] = nextItemType 43 itemViewTypeToViewBinderMap[nextItemType] = viewBinder 44 nextItemType++ 45 return this 46 } 47 buildnull48 fun build() = RecyclerViewAdapter(itemClassToItemViewTypeMap, itemViewTypeToViewBinderMap) 49 } 50 51 class ViewHolder(view: View) : RecyclerView.ViewHolder(view) 52 53 private var data: List<Any> = emptyList() 54 55 fun updateData(entries: List<Any>) { 56 this.data = entries 57 notifyDataSetChanged() 58 } 59 onCreateViewHoldernull60 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 61 val viewBinder = checkNotNull(itemViewTypeToViewBinderMap[viewType]) 62 return ViewHolder(viewBinder.newView(parent)) 63 } 64 onBindViewHoldernull65 override fun onBindViewHolder(holder: ViewHolder, position: Int) { 66 val viewBinder: ViewBinder<Any, View> = 67 checkNotNull(itemViewTypeToViewBinderMap[getItemViewType(position)]) 68 as ViewBinder<Any, View> 69 val item = data[position] 70 viewBinder.bind(holder.itemView, item, position) 71 } 72 getItemViewTypenull73 override fun getItemViewType(position: Int): Int { 74 val clazz = data[position].javaClass 75 return checkNotNull(itemClassToItemViewTypeMap[clazz]) 76 } 77 getItemCountnull78 override fun getItemCount(): Int { 79 return data.size 80 } 81 } 82