Я использую обзор переработчика, который происходит от базового переработчика.Это код для моего базового рециркулятора:
abstract class BaseRecyclerAdapter<B : ViewDataBinding> : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
open lateinit var binding: B
private lateinit var context: Context
private var lastPosition = 0
fun bind(parent: ViewGroup, layout: Int): ViewHolder {
context = parent.context
val layoutInflater = LayoutInflater.from(parent.context)
binding = DataBindingUtil.inflate(layoutInflater, layout, parent, false)
return ViewHolder(binding.root)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
fun setAnimation(viewToAnimate: View, position: Int) {
if (position > lastPosition) {
val animation = AnimationUtils.loadAnimation(context, R.anim.list_animation_fall_down)
viewToAnimate.startAnimation(animation)
lastPosition = position
}
}
}
Я расширяю этот класс из моего SearchAdapter следующим кодом:
class SearchAllAdapter(private val activity: DashboardActivity, private val returnVendors: ArrayList<Content>, private val searchVM: SearchVM, private val latLng: LatLng) : BaseRecyclerAdapter<ItemSearchAllVendorBinding>() {
private lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val viewHolder = bind(parent, R.layout.item_search_all_vendor)
binding.searchVM = searchVM
this.context = parent.context
return viewHolder
}
override fun getItemCount(): Int {
return returnVendors.size
}
override fun getItemViewType(position: Int): Int {
return position
}
override fun getItemId(position: Int): Long {
return returnVendors[position].id.toLong()
}
@SuppressLint("SetTextI18n", "SimpleDateFormat")
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (!activity.hasUser) binding.ivSearchAllDeliveringFavorite.visibility = View.GONE
val item = returnVendors[position]
if (item.open && !Hawk.contains(Constants.CONFIGURATION_PLATFORM)) {
val toLocation = Location("").also {
it.latitude = item.latitude
it.longitude = item.longitude
}
val fromLocation = Location("").also {
it.latitude = latLng.latitude
it.longitude = latLng.longitude
}
val distance = fromLocation.distanceTo(toLocation)
val eta = Math(activity.app, distance, item.preparationTime).getETA(item.bufferTime)
if (eta > 45) {
binding.flSearchAllDeliveringEta.background = ResourcesCompat.getDrawable(context.resources, R.drawable.bg_delivery_time_accent, null)
binding.ivSearchAllDeliveringEta.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_vendor_state_out, null))
}
binding.tvSearchAllDeliveringEta.text = "$eta MIN"
} else {
binding.flSearchAllDeliveringEta.background = ResourcesCompat.getDrawable(context.resources, R.drawable.bg_delivery_time_close, null)
binding.ivSearchAllDeliveringEta.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_vendor_state_closed, null))
val cal = Calendar.getInstance()
val openingCal = Calendar.getInstance()
try {
val openingTime = activity.app.sdf.parse(item.openAt)
openingCal.time = openingTime
val openingTimeFormat = SimpleDateFormat("h:mm a")
when {
openingCal.get(Calendar.DATE) - cal.get(Calendar.DATE) == 0 -> binding.tvSearchAllDeliveringEta.text = context.getString(R.string.tv_closed_today) + " " + openingTimeFormat.format(openingTime)
openingCal.get(Calendar.DATE) - cal.get(Calendar.DATE) in 1 downTo 0 -> binding.tvSearchAllDeliveringEta.text = context.getString(R.string.tv_closed_tomorrow)
else -> binding.tvSearchAllDeliveringEta.text = context.getString(R.string.tv_closed_on) + " " + openingCal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault())
}
} catch (error: NullPointerException) {
binding.tvSearchAllDeliveringEta.text = context.getString(R.string.label_closed)
}
}
binding.cvSearchAllDeliveringContainer.tag = item
binding.ivSearchAllDeliveringFavorite.tag = item.id
binding.tvSearchAllDeliveringItem.text = item.name
item.image?.let {
when {
!item.image.isNullOrEmpty() -> {
GlideApp.with(context)
.load(item.image)
.centerCrop()
.fitCenter()
.into(binding.ivSearchAllDeliveringFood)
}
else -> {
binding.ivSearchAllDeliveringFood.setImageDrawable(null)
}
}
}
val priceRange = when {
item.priceRange == "LOW" -> String.format("\u20B1")
item.priceRange == "MEDIUM" -> String.format("\u20B1\u20B1")
else -> String.format("\u20B1\u20B1\u20B1")
}
binding.tvSearchAllDeliveringCategories.text = priceRange
for (category in item.categories) {
if (binding.tvSearchAllDeliveringCategories.text.isNotEmpty()) binding.tvSearchAllDeliveringCategories.text =
"${binding.tvSearchAllDeliveringCategories.text} • ${category.name}"
else binding.tvSearchAllDeliveringCategories.text = category.name
}
setAnimation(holder.itemView, position)
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
super.onViewRecycled(holder)
binding.ivSearchAllDeliveringFood.setImageDrawable(null)
}
}
Все работает нормально, за исключением того, что после загрузки нескольких элементов яget OOM .
Главное, что я заметил в поведении, это то, что при прокрутке память продолжает расти и не падает до выделения памяти перед прокруткой.Кажется, он не перезапускает представления после того, как он больше не виден.
Разрешение изображения довольно большое, но я не думаю, что это проблема, поскольку память продолжает накапливаться после каждой прокрутки, вызывающей OOM.
Любое предложение или идея, что вызывает эту проблему?