Second attempt for correct passes AsyncListDiffer

This commit is contained in:
Arty Bishop committed 2021-04-02 22:22:36 +01:00
1 parent af49acf4d9
commit cfd1a2f2b8
3 files changed
+45 -41

No files matched your search

@@ -21,6 +21,8 @@ import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.model.SatPass import com.rtbishop.look4sat.data.model.SatPass
@@ -30,46 +32,48 @@ import com.rtbishop.look4sat.utility.navigateSafe
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
class PassesAdapter(private val shouldUseUTC: Boolean = false) : class PassesAdapter(private val isUTC: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var satPassList: MutableList<SatPass> = mutableListOf() private val diffCallback = object : DiffUtil.ItemCallback<SatPass>() {
override fun areItemsTheSame(oldItem: SatPass, newItem: SatPass): Boolean {
return oldItem.catNum == newItem.catNum && oldItem.startDate == newItem.startDate
}
fun setList(list: MutableList<SatPass>) { override fun areContentsTheSame(oldItem: SatPass, newItem: SatPass): Boolean {
satPassList = list return oldItem.progress == newItem.progress
notifyDataSetChanged() }
}
private val differ = AsyncListDiffer(this, diffCallback)
private var allPasses = emptyList<SatPass>()
private var currentPasses = emptyList<SatPass>()
fun submitList(passes: List<SatPass>) {
allPasses = passes.map { it.copy() }
currentPasses = passes.map { it.copy() }
tickDiffer(System.currentTimeMillis())
} }
fun tickPasses(timeNow: Long) { fun tickDiffer(timeNow: Long) {
val iterator = satPassList.listIterator() val list = currentPasses.map { it.copy() }
while (iterator.hasNext()) { list.forEach { pass ->
val satPass = iterator.next() if (!pass.isDeepSpace) {
if (!satPass.isDeepSpace) { val timeStart = pass.startDate.time
if (satPass.progress < 100) { if (timeNow > timeStart) {
val timeStart = satPass.startDate.time val timeEnd = pass.endDate.time
if (timeNow > timeStart) { val deltaNow = timeNow.minus(timeStart).toFloat()
val timeEnd = satPass.endDate.time val deltaTotal = timeEnd.minus(timeStart).toFloat()
val index = satPassList.indexOf(satPass) pass.progress = ((deltaNow / deltaTotal) * 100).toInt()
val deltaNow = timeNow.minus(timeStart).toFloat()
val deltaTotal = timeEnd.minus(timeStart).toFloat()
satPass.progress = ((deltaNow / deltaTotal) * 100).toInt()
notifyItemChanged(index)
}
} else {
val index = satPassList.indexOf(satPass)
iterator.remove()
notifyItemRemoved(index)
} }
} }
} }
currentPasses = list.filter { pass -> pass.progress < 100 }
differ.submitList(currentPasses)
} }
override fun getItemCount(): Int { override fun getItemCount() = differ.currentList.size
return satPassList.size
}
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
return if (satPassList[position].isDeepSpace) 1 return if (differ.currentList[position].isDeepSpace) 1
else 0 else 0
} }
@@ -82,10 +86,11 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val pass = differ.currentList[position]
if (holder.itemViewType == 0) { if (holder.itemViewType == 0) {
(holder as SatPassLeoHolder).bind(satPassList[position], position, shouldUseUTC) (holder as SatPassLeoHolder).bind(pass, differ.currentList.indexOf(pass), isUTC)
} else { } else {
(holder as SatPassGeoHolder).bind(satPassList[position], position) (holder as SatPassGeoHolder).bind(pass, differ.currentList.indexOf(pass))
} }
} }
@@ -103,7 +108,7 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
private val startFormat = SimpleDateFormat(startTimeFormat, Locale.getDefault()) private val startFormat = SimpleDateFormat(startTimeFormat, Locale.getDefault())
private val endFormat = SimpleDateFormat(endTimeFormat, Locale.getDefault()) private val endFormat = SimpleDateFormat(endTimeFormat, Locale.getDefault())
fun bind(satPass: SatPass, position: Int, shouldUseUTC: Boolean) { fun bind(satPass: SatPass, passIndex: Int, shouldUseUTC: Boolean) {
binding.apply { binding.apply {
if (shouldUseUTC) { if (shouldUseUTC) {
startFormat.timeZone = timeZoneUTC startFormat.timeZone = timeZoneUTC
@@ -122,7 +127,7 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
itemView.setOnClickListener { itemView.setOnClickListener {
if (satPass.progress < 100) { if (satPass.progress < 100) {
val bundle = bundleOf("index" to position) val bundle = bundleOf("index" to passIndex)
itemView.findNavController().navigateSafe(R.id.action_passes_to_polar, bundle) itemView.findNavController().navigateSafe(R.id.action_passes_to_polar, bundle)
} }
} }
@@ -144,7 +149,7 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
private val altFormat = itemView.context.getString(R.string.pat_altitude) private val altFormat = itemView.context.getString(R.string.pat_altitude)
private val elevFormat = itemView.context.getString(R.string.pat_elevation) private val elevFormat = itemView.context.getString(R.string.pat_elevation)
fun bind(satPass: SatPass, position: Int) { fun bind(satPass: SatPass, passIndex: Int) {
binding.apply { binding.apply {
passGeoSatName.text = satPass.name passGeoSatName.text = satPass.name
passGeoSatId.text = String.format(satIdFormat, satPass.catNum) passGeoSatId.text = String.format(satIdFormat, satPass.catNum)
@@ -154,7 +159,7 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
} }
itemView.setOnClickListener { itemView.setOnClickListener {
val bundle = bundleOf("index" to position) val bundle = bundleOf("index" to passIndex)
itemView.findNavController().navigateSafe(R.id.action_passes_to_polar, bundle) itemView.findNavController().navigateSafe(R.id.action_passes_to_polar, bundle)
} }
} }
@@ -51,7 +51,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes) {
adapter = passesAdapter adapter = passesAdapter
isVerticalScrollBarEnabled = false isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false // (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark)) addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark))
} }
passesRefresh.setOnClickListener { viewModel.forceCalculation() } passesRefresh.setOnClickListener { viewModel.forceCalculation() }
@@ -72,7 +72,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes) {
when (result) { when (result) {
is Result.Success -> { is Result.Success -> {
passes = result.data.toMutableList() passes = result.data.toMutableList()
passesAdapter.setList(passes) passesAdapter.submitList(passes)
binding.apply { binding.apply {
passesError.visibility = View.INVISIBLE passesError.visibility = View.INVISIBLE
passesProgress.visibility = View.INVISIBLE passesProgress.visibility = View.INVISIBLE
@@ -115,7 +115,8 @@ class PassesFragment : Fragment(R.layout.fragment_passes) {
val millisBeforeEnd = lastPass.endDate.time.minus(timeNow) val millisBeforeEnd = lastPass.endDate.time.minus(timeNow)
binding.passesTimer.text = millisBeforeEnd.formatForTimer() binding.passesTimer.text = millisBeforeEnd.formatForTimer()
} }
passesAdapter.tickPasses(timeNow) // passesAdapter.tickPasses(timeNow)
passesAdapter.tickDiffer(timeNow)
} else { } else {
binding.passesTimer.text = 0L.formatForTimer() binding.passesTimer.text = 0L.formatForTimer()
} }
@@ -46,9 +46,7 @@ class PolarViewModel @Inject constructor(
fun getPass(passId: Int) = liveData { fun getPass(passId: Int) = liveData {
passesRepo.passes.collect { passes -> passesRepo.passes.collect { passes ->
if (passes is Result.Success) { if (passes is Result.Success) emit(passes.data[passId])
emit(passes.data[passId])
}
} }
} }