Updated EventPageFragment.kt to have access to its own ViewModel and, by extension, its own reference to the database, which forgoes the need to transport data from EventFragment.kt through StudIPEventPageAdapter.kt to EventPageFragment.kt and allows for filtering for a specific day's items through the database rather than needing to iterate through the list via an extension function manually. Also implemented DiffUtil to perform individual updates rather than calling notifyDataSetChanged() every time a single item has been changed.

This commit is contained in:
denizk0461
2023-04-28 11:18:05 +02:00
parent ee0934f29b
commit aa5d32e64a
11 changed files with 200 additions and 142 deletions
@@ -3,7 +3,9 @@ package com.denizk0461.studip.adapter
import android.content.res.ColorStateList
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.denizk0461.studip.data.AppDiffUtilCallback
import com.google.android.material.R
import com.denizk0461.studip.data.getThemedColor
import com.denizk0461.studip.data.parseToMinutes
@@ -12,29 +14,30 @@ import com.denizk0461.studip.databinding.ItemEventBinding
import java.util.*
/**
* Custom RecyclerView adapter that lays out the Stud.IP events of a given day.
* Custom RecyclerView adapter that lays out the Stud.IP events for a given day.
*
* @param events list of all events (still not filtered by day at this point)
* @param currentDay current day that is used to show only events of a given day (0 = Monday,
* @param currentDay current day that is used to show only a given day's events (0 = Monday,
* 4 = Friday)
* @param onClickListener used for listening to clicks and long presses
*/
class StudIPEventItemAdapter(
events: List<StudIPEvent>,
private val currentDay: Int,
private val onClickListener: OnClickListener,
) : RecyclerView.Adapter<StudIPEventItemAdapter.EventViewHolder>() {
// Filter events to only show those of a given day
private val filteredEvents: List<StudIPEvent> = events.filter { it.day == currentDay }
/**
* List of all events (still not filtered by day at this point)
*/
private var events: MutableList<StudIPEvent> = mutableListOf()
/*
/**
* Retrieve an instance of Calendar to check whether the adapter's day matches the current day.
* TODO this can be optimised by checking in StudIPEventPageAdapter.kt and delivering a boolean
* TODO this can be optimised by checking in EventPageFragment.kt and delivering a boolean
*/
private val currentCalendar = Calendar.getInstance()
/*
/**
* Used to disallow highlighting more than one course at a time, since only a single course
* could be coming up at a given time.
*/
@@ -58,12 +61,11 @@ class StudIPEventItemAdapter(
}
// Set the amount of items to the size of the filtered list, so only events of the current day
override fun getItemCount(): Int = filteredEvents.size
override fun getItemCount(): Int = events.size
// TODO inflate a view saying "no events" if none are available for a given day
override fun onBindViewHolder(holder: EventViewHolder, position: Int) {
// Retrieve item for current position
val currentItem = filteredEvents[position]
val currentItem = events[position]
// Set up text fields with corresponding values
holder.binding.textTitle.text = currentItem.title
@@ -117,6 +119,26 @@ class StudIPEventItemAdapter(
}
}
/**
* Updates the data and calculates the difference between the old dataset and the newly provided
* dataset.
*
* @param newData new dataset to be displayed
*/
fun setNewData(newData: List<StudIPEvent>) {
// Calculate the difference between the old list and the new list
val diffResult = DiffUtil.calculateDiff(AppDiffUtilCallback(events, newData))
// Remove all items from the list
events.clear()
// Add all items from the new list
events.addAll(newData)
// Tell the DiffUtil which items have changed between the two lists
diffResult.dispatchUpdatesTo(this)
}
/**
* Checks if a given course is the next course coming up. This is done by checking whether the
* day of the course matches the current real world day, as well as by evaluating if the end
@@ -131,7 +153,6 @@ class StudIPEventItemAdapter(
(calendar.get(Calendar.DAY_OF_WEEK) == this.day.toCalendarDay()) &&
((calendar.get(Calendar.MINUTE) + calendar.get(Calendar.HOUR_OF_DAY) * 60) < this.timeslotEnd.parseToMinutes())
// Converts day as defined in StudIPEvent.kt to day from Calendar
/**
* Converts a numeric value as defined in StudIPEvent.kt to a calendar day. Used to convert from
* American convention (where Sunday is the first day, 1 = Sunday, 2 = Monday, 7 = Saturday) to