Partial ProductAdapter updates, drop direct bindViewHolder calls

This commit is contained in:
kitsunyan
2020-07-04 12:22:22 +03:00
parent 930e195772
commit 0d4aedad87
2 changed files with 87 additions and 75 deletions
@@ -284,6 +284,8 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
}
private enum class Payload { REFRESH, STATUS }
private class HeaderViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val icon = itemView.findViewById<ImageView>(R.id.icon)!!
val name = itemView.findViewById<TextView>(R.id.name)!!
@@ -781,33 +783,39 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
private var action: Action? = null
fun setAction(recyclerView: RecyclerView, action: Action?) {
fun setAction(action: Action?) {
if (this.action != action) {
val translate = this.action == null || action == null ||
this.action == Action.CANCEL || action == Action.CANCEL
this.action = action
if (items.getOrNull(0) is Item.HeaderItem) {
val holder = recyclerView.findViewHolderForAdapterPosition(0)
holder?.let { bindViewHolder(holder, 0) }
val index = items.indexOfFirst { it is Item.HeaderItem }
if (index >= 0) {
if (translate) {
notifyItemChanged(index)
} else {
notifyItemChanged(index, Payload.REFRESH)
}
}
}
}
private var status: Status? = null
fun setStatus(recyclerView: RecyclerView, status: Status?) {
val notify = (this.status == null) != (status == null)
fun setStatus(status: Status?) {
val translate = (this.status == null) != (status == null)
if (this.status != status) {
this.status = status
if (items.getOrNull(0) is Item.HeaderItem) {
if (notify) {
notifyItemChanged(0)
val index = items.indexOfFirst { it is Item.HeaderItem }
if (index >= 0) {
if (translate) {
notifyItemChanged(index)
val from = items.indexOfFirst { it is Item.ReleaseItem }
val to = items.indexOfLast { it is Item.ReleaseItem }
if (from in 0 .. to) {
notifyItemRangeChanged(from, to - from + 1)
}
} else {
val holder = recyclerView.findViewHolderForAdapterPosition(0)
holder?.let { bindViewHolder(holder, 0) }
notifyItemChanged(index, Payload.STATUS)
}
}
}
@@ -840,8 +848,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
ViewType.SWITCH -> SwitchViewHolder(parent.inflate(R.layout.switch_item)).apply {
itemView.setOnClickListener {
val positions = items.asSequence().mapIndexedNotNull { index, item -> if (item is Item.HeaderItem ||
item is Item.SwitchItem) index else null }
val switchItem = items[adapterPosition] as Item.SwitchItem
val productPreference = when (switchItem.switchType) {
SwitchType.IGNORE_ALL_UPDATES -> {
@@ -853,13 +859,8 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
}
ProductPreferences[switchItem.packageName] = productPreference
val recyclerView = itemView.parent as RecyclerView
positions.forEach {
val holder = recyclerView.findViewHolderForAdapterPosition(it)
if (holder != null) {
bindViewHolder(holder, it)
}
}
items.asSequence().mapIndexedNotNull { index, item -> if (item is Item.HeaderItem ||
item is Item.SectionItem) index else null }.forEach { notifyItemChanged(it, Payload.REFRESH) }
callbacks.onPreferenceChanged(productPreference)
}
}
@@ -871,14 +872,14 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
expanded += sectionItem.expandType
items[position] = Item.SectionItem(sectionItem.sectionType, sectionItem.expandType, emptyList(),
sectionItem.items.size + sectionItem.collapseCount)
bindViewHolder(this, position)
notifyItemChanged(adapterPosition, Payload.REFRESH)
items.addAll(position + 1, sectionItem.items)
notifyItemRangeInserted(position + 1, sectionItem.items.size)
} else if (sectionItem.collapseCount > 0) {
expanded -= sectionItem.expandType
items[position] = Item.SectionItem(sectionItem.sectionType, sectionItem.expandType,
items.subList(position + 1, position + 1 + sectionItem.collapseCount).toList(), 0)
bindViewHolder(this, position)
notifyItemChanged(adapterPosition, Payload.REFRESH)
repeat(sectionItem.collapseCount) { items.removeAt(position + 1) }
notifyItemRangeRemoved(position + 1, sectionItem.collapseCount)
}
@@ -900,7 +901,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
items.addAll(position, expandItem.items)
if (position > 0) {
// Update decorations
notifyItemChanged(position - 1)
notifyItemChanged(position - 1, Payload.REFRESH)
}
notifyItemRemoved(position)
notifyItemRangeInserted(position, expandItem.items.size)
@@ -944,6 +945,10 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
onBindViewHolder(holder, position, emptyList())
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: List<Any>) {
val context = holder.itemView.context
val item = items[position]
when (getItemEnumViewType(position)) {
@@ -951,6 +956,9 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
holder as HeaderViewHolder
item as Item.HeaderItem
val installedItem = installedItem
val updateStatus = Payload.STATUS in payloads
val updateAll = !updateStatus
if (updateAll) {
if (item.product.icon.isNotEmpty()) {
holder.icon.load(PicassoDownloader.createIconUri(holder.icon, item.product.icon, item.repository)) {
placeholder(holder.progressIcon)
@@ -969,7 +977,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
?: context.getString(R.string.unknown)
holder.packageName.text = item.product.packageName
val action = action
val status = status
holder.action.visibility = if (action == null) View.GONE else View.VISIBLE
if (action != null) {
holder.action.setText(action.titleResId)
@@ -978,6 +985,9 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
holder.action.backgroundTintList = if (action == Action.CANCEL)
holder.actionTintCancel else holder.actionTintNormal
}
}
if (updateAll || updateStatus) {
val status = status
holder.statusLayout.visibility = if (status != null) View.VISIBLE else View.GONE
if (status != null) {
when (status) {
@@ -1000,6 +1010,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
}::class
}
}
Unit
}
ViewType.SWITCH -> {
@@ -148,8 +148,12 @@ class ProductFragment(): ScreenFragment(), ProductAdapter.Callbacks {
if (firstChanged || productChanged || installedItemChanged) {
layoutManagerState?.let { recyclerView?.layoutManager!!.onRestoreInstanceState(it) }
layoutManagerState = null
if (firstChanged || productChanged) {
this.products = products
}
if (firstChanged || installedItemChanged) {
this.installedItem = installedItem.value
}
val recyclerView = recyclerView!!
val adapter = recyclerView.adapter as ProductAdapter
if (firstChanged || productChanged) {
@@ -231,7 +235,7 @@ class ProductFragment(): ScreenFragment(), ProductAdapter.Callbacks {
installedItem != null -> ProductAdapter.Action.DETAILS
else -> null
}
(recyclerView.adapter as ProductAdapter).setAction(recyclerView, adapterAction)
(recyclerView.adapter as ProductAdapter).setAction(adapterAction)
Action.values().find { it.adapterAction == adapterAction }?.let { actions -= it }
}
@@ -256,10 +260,7 @@ class ProductFragment(): ScreenFragment(), ProductAdapter.Callbacks {
this.downloading = downloading
updateButtons()
}
val recyclerView = recyclerView
if (recyclerView != null) {
(recyclerView.adapter as ProductAdapter).setStatus(recyclerView, status)
}
(recyclerView?.adapter as? ProductAdapter)?.setStatus(status)
if (state is DownloadService.State.Success && isResumed) {
state.consume()
screenActivity.startPackageInstaller(state.release.cacheFileName)