mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-24 02:41:51 +01:00
Pass ViewHolder
on bind to RecyclerView items instead of ViewBinding
This change lets items get the updated position of their view holder in the adapter. Fixes an issue where the position of items was not updated after being removed from a `SelectableGenericAdapter`.
This commit is contained in:
parent
bb922100cb
commit
8991ccac65
@ -84,7 +84,8 @@ private typealias InteractionFunction = (appItem : AppItem) -> Unit
|
|||||||
class AppViewItem(var layoutType : LayoutType, private val item : AppItem, private val missingIcon : Bitmap, private val onClick : InteractionFunction, private val onLongClick : InteractionFunction) : GenericListItem<LayoutBinding<*>>() {
|
class AppViewItem(var layoutType : LayoutType, private val item : AppItem, private val missingIcon : Bitmap, private val onClick : InteractionFunction, private val onLongClick : InteractionFunction) : GenericListItem<LayoutBinding<*>>() {
|
||||||
override fun getViewBindingFactory() = LayoutBindingFactory(layoutType)
|
override fun getViewBindingFactory() = LayoutBindingFactory(layoutType)
|
||||||
|
|
||||||
override fun bind(binding : LayoutBinding<*>, position : Int) {
|
override fun bind(holder : GenericViewHolder<LayoutBinding<*>>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
binding.textTitle.text = item.title
|
binding.textTitle.text = item.title
|
||||||
binding.textSubtitle.text = item.subTitle ?: item.loaderResultString(binding.root.context)
|
binding.textSubtitle.text = item.subTitle ?: item.loaderResultString(binding.root.context)
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ open class GenericAdapter : RecyclerView.Adapter<GenericViewHolder<ViewBinding>>
|
|||||||
override fun onBindViewHolder(holder : GenericViewHolder<ViewBinding>, position : Int) {
|
override fun onBindViewHolder(holder : GenericViewHolder<ViewBinding>, position : Int) {
|
||||||
currentItems[position].apply {
|
currentItems[position].apply {
|
||||||
adapter = this@GenericAdapter
|
adapter = this@GenericAdapter
|
||||||
bind(holder.binding, position)
|
bind(holder, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ abstract class GenericListItem<V : ViewBinding> {
|
|||||||
|
|
||||||
abstract fun getViewBindingFactory() : ViewBindingFactory
|
abstract fun getViewBindingFactory() : ViewBindingFactory
|
||||||
|
|
||||||
abstract fun bind(binding : V, position : Int)
|
abstract fun bind(holder : GenericViewHolder<V>, position : Int)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for filtering
|
* Used for filtering
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package emu.skyline.adapter
|
package emu.skyline.adapter
|
||||||
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import emu.skyline.data.GpuDriverMetadata
|
import emu.skyline.data.GpuDriverMetadata
|
||||||
import emu.skyline.databinding.GpuDriverItemBinding
|
import emu.skyline.databinding.GpuDriverItemBinding
|
||||||
|
|
||||||
@ -18,12 +19,15 @@ open class GpuDriverViewItem(
|
|||||||
var onDelete : ((position : Int, wasChecked : Boolean) -> Unit)? = null,
|
var onDelete : ((position : Int, wasChecked : Boolean) -> Unit)? = null,
|
||||||
var onClick : (() -> Unit)? = null
|
var onClick : (() -> Unit)? = null
|
||||||
) : SelectableGenericListItem<GpuDriverItemBinding>() {
|
) : SelectableGenericListItem<GpuDriverItemBinding>() {
|
||||||
private var position = -1
|
private var holder : GenericViewHolder<GpuDriverItemBinding>? = null
|
||||||
|
private val adapterPosition get() = holder?.adapterPosition ?: RecyclerView.NO_POSITION
|
||||||
|
|
||||||
override fun getViewBindingFactory() = GpuDriverBindingFactory
|
override fun getViewBindingFactory() = GpuDriverBindingFactory
|
||||||
|
|
||||||
override fun bind(binding : GpuDriverItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<GpuDriverItemBinding>, position : Int) {
|
||||||
this.position = position
|
this.holder = holder
|
||||||
|
val binding = holder.binding
|
||||||
|
|
||||||
binding.name.text = driverMetadata.name
|
binding.name.text = driverMetadata.name
|
||||||
|
|
||||||
if (driverMetadata.packageVersion.isNotBlank() || driverMetadata.packageVersion.isNotBlank()) {
|
if (driverMetadata.packageVersion.isNotBlank() || driverMetadata.packageVersion.isNotBlank()) {
|
||||||
@ -38,17 +42,21 @@ open class GpuDriverViewItem(
|
|||||||
binding.radioButton.isChecked = position == selectableAdapter?.selectedPosition
|
binding.radioButton.isChecked = position == selectableAdapter?.selectedPosition
|
||||||
|
|
||||||
binding.root.setOnClickListener {
|
binding.root.setOnClickListener {
|
||||||
selectableAdapter?.selectAndNotify(position)
|
selectableAdapter?.selectAndNotify(adapterPosition)
|
||||||
onClick?.invoke()
|
onClick?.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
onDelete?.let { onDelete ->
|
onDelete?.let { onDelete ->
|
||||||
binding.deleteButton.visibility = ViewGroup.VISIBLE
|
binding.deleteButton.visibility = ViewGroup.VISIBLE
|
||||||
binding.deleteButton.setOnClickListener {
|
binding.deleteButton.setOnClickListener {
|
||||||
val wasChecked = position == selectableAdapter?.selectedPosition
|
val pos = adapterPosition
|
||||||
selectableAdapter?.removeItemAt(position)
|
if (pos == RecyclerView.NO_POSITION)
|
||||||
|
return@setOnClickListener
|
||||||
|
|
||||||
onDelete.invoke(position, wasChecked)
|
val wasChecked = pos == selectableAdapter?.selectedPosition
|
||||||
|
selectableAdapter?.removeItemAt(pos)
|
||||||
|
|
||||||
|
onDelete.invoke(pos, wasChecked)
|
||||||
}
|
}
|
||||||
} ?: run {
|
} ?: run {
|
||||||
binding.deleteButton.visibility = ViewGroup.GONE
|
binding.deleteButton.visibility = ViewGroup.GONE
|
||||||
|
@ -22,7 +22,8 @@ class HeaderRomFilterItem(private val formats : List<RomFormat>, selectedFormat
|
|||||||
|
|
||||||
override fun getViewBindingFactory() = HeaderRomFilterBindingFactory
|
override fun getViewBindingFactory() = HeaderRomFilterBindingFactory
|
||||||
|
|
||||||
override fun bind(binding : HeaderRomFilterBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<HeaderRomFilterBinding>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
binding.chipGroup.removeViews(1, binding.chipGroup.childCount - 1)
|
binding.chipGroup.removeViews(1, binding.chipGroup.childCount - 1)
|
||||||
for (format in formats) {
|
for (format in formats) {
|
||||||
binding.chipGroup.addView(Chip(binding.root.context, null, R.attr.chipChoiceStyle).apply { text = format.name })
|
binding.chipGroup.addView(Chip(binding.root.context, null, R.attr.chipChoiceStyle).apply { text = format.name })
|
||||||
|
@ -15,8 +15,8 @@ object HeaderBindingFactory : ViewBindingFactory {
|
|||||||
class HeaderViewItem(private val text : String) : GenericListItem<SectionItemBinding>() {
|
class HeaderViewItem(private val text : String) : GenericListItem<SectionItemBinding>() {
|
||||||
override fun getViewBindingFactory() = HeaderBindingFactory
|
override fun getViewBindingFactory() = HeaderBindingFactory
|
||||||
|
|
||||||
override fun bind(binding : SectionItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<SectionItemBinding>, position : Int) {
|
||||||
binding.textTitle.text = text
|
holder.binding.textTitle.text = text
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = ""
|
override fun toString() = ""
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package emu.skyline.adapter.controller
|
package emu.skyline.adapter.controller
|
||||||
|
|
||||||
import emu.skyline.adapter.GenericListItem
|
import emu.skyline.adapter.GenericListItem
|
||||||
|
import emu.skyline.adapter.GenericViewHolder
|
||||||
import emu.skyline.databinding.ControllerItemBinding
|
import emu.skyline.databinding.ControllerItemBinding
|
||||||
import emu.skyline.di.getInputManager
|
import emu.skyline.di.getInputManager
|
||||||
import emu.skyline.input.ButtonGuestEvent
|
import emu.skyline.input.ButtonGuestEvent
|
||||||
@ -15,12 +16,13 @@ import emu.skyline.input.ButtonId
|
|||||||
* This item is used to display a particular [button] mapping for the controller
|
* This item is used to display a particular [button] mapping for the controller
|
||||||
*/
|
*/
|
||||||
class ControllerButtonViewItem(private val controllerId : Int, val button : ButtonId, private val onClick : (item : ControllerButtonViewItem, position : Int) -> Unit) : ControllerViewItem() {
|
class ControllerButtonViewItem(private val controllerId : Int, val button : ButtonId, private val onClick : (item : ControllerButtonViewItem, position : Int) -> Unit) : ControllerViewItem() {
|
||||||
override fun bind(binding : ControllerItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerItemBinding>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
content = button.long?.let { binding.root.context.getString(it) } ?: button.toString()
|
content = button.long?.let { binding.root.context.getString(it) } ?: button.toString()
|
||||||
val guestEvent = ButtonGuestEvent(controllerId, button)
|
val guestEvent = ButtonGuestEvent(controllerId, button)
|
||||||
subContent = binding.root.context.getInputManager().eventMap.filter { it.value is ButtonGuestEvent && it.value == guestEvent }.keys.firstOrNull()?.toString() ?: ""
|
subContent = binding.root.context.getInputManager().eventMap.filter { it.value is ButtonGuestEvent && it.value == guestEvent }.keys.firstOrNull()?.toString() ?: ""
|
||||||
|
|
||||||
super.bind(binding, position)
|
super.bind(holder, position)
|
||||||
|
|
||||||
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package emu.skyline.adapter.controller
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import emu.skyline.adapter.GenericListItem
|
import emu.skyline.adapter.GenericListItem
|
||||||
|
import emu.skyline.adapter.GenericViewHolder
|
||||||
import emu.skyline.adapter.ViewBindingFactory
|
import emu.skyline.adapter.ViewBindingFactory
|
||||||
import emu.skyline.adapter.inflater
|
import emu.skyline.adapter.inflater
|
||||||
import emu.skyline.databinding.ControllerCheckboxItemBinding
|
import emu.skyline.databinding.ControllerCheckboxItemBinding
|
||||||
@ -19,7 +20,8 @@ object ControllerCheckBoxBindingFactory : ViewBindingFactory {
|
|||||||
class ControllerCheckBoxViewItem(var title : String, var summary : String, var checked : Boolean, private val onCheckedChange : (item : ControllerCheckBoxViewItem, position : Int) -> Unit) : GenericListItem<ControllerCheckboxItemBinding>() {
|
class ControllerCheckBoxViewItem(var title : String, var summary : String, var checked : Boolean, private val onCheckedChange : (item : ControllerCheckBoxViewItem, position : Int) -> Unit) : GenericListItem<ControllerCheckboxItemBinding>() {
|
||||||
override fun getViewBindingFactory() = ControllerCheckBoxBindingFactory
|
override fun getViewBindingFactory() = ControllerCheckBoxBindingFactory
|
||||||
|
|
||||||
override fun bind(binding : ControllerCheckboxItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerCheckboxItemBinding>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
binding.textTitle.isGone = title.isEmpty()
|
binding.textTitle.isGone = title.isEmpty()
|
||||||
binding.textTitle.text = title
|
binding.textTitle.text = title
|
||||||
binding.textSubtitle.isGone = summary.isEmpty()
|
binding.textSubtitle.isGone = summary.isEmpty()
|
||||||
|
@ -19,7 +19,8 @@ import emu.skyline.input.JoyConLeftController
|
|||||||
* @param type The type of controller setting this item is displaying
|
* @param type The type of controller setting this item is displaying
|
||||||
*/
|
*/
|
||||||
class ControllerGeneralViewItem(private val controllerId : Int, val type : GeneralType, private val onClick : (item : ControllerGeneralViewItem, position : Int) -> Unit) : ControllerViewItem() {
|
class ControllerGeneralViewItem(private val controllerId : Int, val type : GeneralType, private val onClick : (item : ControllerGeneralViewItem, position : Int) -> Unit) : ControllerViewItem() {
|
||||||
override fun bind(binding : ControllerItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerItemBinding>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
val context = binding.root.context
|
val context = binding.root.context
|
||||||
val controller = context.getInputManager().controllers[controllerId]!!
|
val controller = context.getInputManager().controllers[controllerId]!!
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ class ControllerGeneralViewItem(private val controllerId : Int, val type : Gener
|
|||||||
|
|
||||||
GeneralType.SetupGuide -> context.getString(R.string.setup_guide_description)
|
GeneralType.SetupGuide -> context.getString(R.string.setup_guide_description)
|
||||||
}
|
}
|
||||||
super.bind(binding, position)
|
super.bind(holder, position)
|
||||||
|
|
||||||
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package emu.skyline.adapter.controller
|
|||||||
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import emu.skyline.adapter.GenericListItem
|
import emu.skyline.adapter.GenericListItem
|
||||||
|
import emu.skyline.adapter.GenericViewHolder
|
||||||
import emu.skyline.adapter.ViewBindingFactory
|
import emu.skyline.adapter.ViewBindingFactory
|
||||||
import emu.skyline.adapter.inflater
|
import emu.skyline.adapter.inflater
|
||||||
import emu.skyline.databinding.ControllerHeaderBinding
|
import emu.skyline.databinding.ControllerHeaderBinding
|
||||||
@ -13,8 +14,8 @@ object ControllerHeaderBindingFactory : ViewBindingFactory {
|
|||||||
class ControllerHeaderItem(private val text : String) : GenericListItem<ControllerHeaderBinding>() {
|
class ControllerHeaderItem(private val text : String) : GenericListItem<ControllerHeaderBinding>() {
|
||||||
override fun getViewBindingFactory() = ControllerHeaderBindingFactory
|
override fun getViewBindingFactory() = ControllerHeaderBindingFactory
|
||||||
|
|
||||||
override fun bind(binding : ControllerHeaderBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerHeaderBinding>, position : Int) {
|
||||||
binding.root.text = text
|
holder.binding.root.text = text
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun areItemsTheSame(other : GenericListItem<ControllerHeaderBinding>) = other is ControllerHeaderItem
|
override fun areItemsTheSame(other : GenericListItem<ControllerHeaderBinding>) = other is ControllerHeaderItem
|
||||||
|
@ -18,7 +18,8 @@ import emu.skyline.input.StickId
|
|||||||
* This item is used to display all information regarding a [stick] and it's mappings for the controller
|
* This item is used to display all information regarding a [stick] and it's mappings for the controller
|
||||||
*/
|
*/
|
||||||
class ControllerStickViewItem(private val controllerId : Int, val stick : StickId, private val onClick : (item : ControllerStickViewItem, position : Int) -> Unit) : ControllerViewItem(stick.toString()) {
|
class ControllerStickViewItem(private val controllerId : Int, val stick : StickId, private val onClick : (item : ControllerStickViewItem, position : Int) -> Unit) : ControllerViewItem(stick.toString()) {
|
||||||
override fun bind(binding : ControllerItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerItemBinding>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
val context = binding.root.context
|
val context = binding.root.context
|
||||||
val inputManager = context.getInputManager()
|
val inputManager = context.getInputManager()
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ class ControllerStickViewItem(private val controllerId : Int, val stick : StickI
|
|||||||
|
|
||||||
subContent = "${context.getString(R.string.button)}: $button\n${context.getString(R.string.up)}: $yAxisPlus\n${context.getString(R.string.down)}: $yAxisMinus\n${context.getString(R.string.left)}: $xAxisMinus\n${context.getString(R.string.right)}: $xAxisPlus"
|
subContent = "${context.getString(R.string.button)}: $button\n${context.getString(R.string.up)}: $yAxisPlus\n${context.getString(R.string.down)}: $yAxisMinus\n${context.getString(R.string.left)}: $xAxisMinus\n${context.getString(R.string.right)}: $xAxisPlus"
|
||||||
|
|
||||||
super.bind(binding, position)
|
super.bind(holder, position)
|
||||||
|
|
||||||
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,14 @@ import emu.skyline.input.ControllerType
|
|||||||
* This item is used to display the [type] of the currently active controller
|
* This item is used to display the [type] of the currently active controller
|
||||||
*/
|
*/
|
||||||
class ControllerTypeViewItem(private val type : ControllerType, private val onClick : (item : ControllerTypeViewItem, position : Int) -> Unit) : ControllerViewItem() {
|
class ControllerTypeViewItem(private val type : ControllerType, private val onClick : (item : ControllerTypeViewItem, position : Int) -> Unit) : ControllerViewItem() {
|
||||||
override fun bind(binding : ControllerItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerItemBinding>, position : Int) {
|
||||||
|
val binding = holder.binding
|
||||||
val context = binding.root.context
|
val context = binding.root.context
|
||||||
|
|
||||||
content = context.getString(R.string.controller_type)
|
content = context.getString(R.string.controller_type)
|
||||||
subContent = context.getString(type.stringRes)
|
subContent = context.getString(type.stringRes)
|
||||||
|
|
||||||
super.bind(binding, position)
|
super.bind(holder, position)
|
||||||
|
|
||||||
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
binding.root.setOnClickListener { onClick.invoke(this, position) }
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package emu.skyline.adapter.controller
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import emu.skyline.adapter.GenericListItem
|
import emu.skyline.adapter.GenericListItem
|
||||||
|
import emu.skyline.adapter.GenericViewHolder
|
||||||
import emu.skyline.adapter.ViewBindingFactory
|
import emu.skyline.adapter.ViewBindingFactory
|
||||||
import emu.skyline.adapter.inflater
|
import emu.skyline.adapter.inflater
|
||||||
import emu.skyline.databinding.ControllerItemBinding
|
import emu.skyline.databinding.ControllerItemBinding
|
||||||
@ -21,8 +22,9 @@ open class ControllerViewItem(var content : String = "", var subContent : String
|
|||||||
|
|
||||||
override fun getViewBindingFactory() = ControllerBindingFactory
|
override fun getViewBindingFactory() = ControllerBindingFactory
|
||||||
|
|
||||||
override fun bind(binding : ControllerItemBinding, position : Int) {
|
override fun bind(holder : GenericViewHolder<ControllerItemBinding>, position : Int) {
|
||||||
this.position = position
|
this.position = position
|
||||||
|
val binding = holder.binding
|
||||||
binding.textTitle.apply {
|
binding.textTitle.apply {
|
||||||
isGone = content.isEmpty()
|
isGone = content.isEmpty()
|
||||||
text = content
|
text = content
|
||||||
|
Loading…
Reference in New Issue
Block a user