summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authort895 <clombardo169@gmail.com>2024-01-08 06:17:01 +0100
committert895 <clombardo169@gmail.com>2024-01-11 05:14:04 +0100
commit78c323c4eb1beb502f1c2b5367ecb8654181c1e0 (patch)
tree1af6c778c1bf86f31189dee74eb3e963349c6021
parentandroid: Create generic adapter and viewholder (diff)
downloadyuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.tar
yuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.tar.gz
yuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.tar.bz2
yuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.tar.lz
yuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.tar.xz
yuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.tar.zst
yuzu-78c323c4eb1beb502f1c2b5367ecb8654181c1e0.zip
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AddonAdapter.kt36
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/FolderAdapter.kt36
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt192
3 files changed, 92 insertions, 172 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AddonAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AddonAdapter.kt
index 15c7ca3c9..94c151325 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AddonAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AddonAdapter.kt
@@ -5,48 +5,28 @@ package org.yuzu.yuzu_emu.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
-import androidx.recyclerview.widget.AsyncDifferConfig
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
import org.yuzu.yuzu_emu.databinding.ListItemAddonBinding
import org.yuzu.yuzu_emu.model.Addon
+import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
-class AddonAdapter : ListAdapter<Addon, AddonAdapter.AddonViewHolder>(
- AsyncDifferConfig.Builder(DiffCallback()).build()
-) {
+class AddonAdapter : AbstractDiffAdapter<Addon, AddonAdapter.AddonViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddonViewHolder {
ListItemAddonBinding.inflate(LayoutInflater.from(parent.context), parent, false)
.also { return AddonViewHolder(it) }
}
- override fun getItemCount(): Int = currentList.size
-
- override fun onBindViewHolder(holder: AddonViewHolder, position: Int) =
- holder.bind(currentList[position])
-
inner class AddonViewHolder(val binding: ListItemAddonBinding) :
- RecyclerView.ViewHolder(binding.root) {
- fun bind(addon: Addon) {
+ AbstractViewHolder<Addon>(binding) {
+ override fun bind(model: Addon) {
binding.root.setOnClickListener {
binding.addonSwitch.isChecked = !binding.addonSwitch.isChecked
}
- binding.title.text = addon.title
- binding.version.text = addon.version
+ binding.title.text = model.title
+ binding.version.text = model.version
binding.addonSwitch.setOnCheckedChangeListener { _, checked ->
- addon.enabled = checked
+ model.enabled = checked
}
- binding.addonSwitch.isChecked = addon.enabled
- }
- }
-
- private class DiffCallback : DiffUtil.ItemCallback<Addon>() {
- override fun areItemsTheSame(oldItem: Addon, newItem: Addon): Boolean {
- return oldItem == newItem
- }
-
- override fun areContentsTheSame(oldItem: Addon, newItem: Addon): Boolean {
- return oldItem == newItem
+ binding.addonSwitch.isChecked = model.enabled
}
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/FolderAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/FolderAdapter.kt
index ab657a7b9..3d8f0bda8 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/FolderAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/FolderAdapter.kt
@@ -8,19 +8,14 @@ import android.text.TextUtils
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
-import androidx.recyclerview.widget.AsyncDifferConfig
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
import org.yuzu.yuzu_emu.databinding.CardFolderBinding
import org.yuzu.yuzu_emu.fragments.GameFolderPropertiesDialogFragment
import org.yuzu.yuzu_emu.model.GameDir
import org.yuzu.yuzu_emu.model.GamesViewModel
+import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesViewModel) :
- ListAdapter<GameDir, FolderAdapter.FolderViewHolder>(
- AsyncDifferConfig.Builder(DiffCallback()).build()
- ) {
+ AbstractDiffAdapter<GameDir, FolderAdapter.FolderViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
@@ -29,18 +24,11 @@ class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesVie
.also { return FolderViewHolder(it) }
}
- override fun onBindViewHolder(holder: FolderAdapter.FolderViewHolder, position: Int) =
- holder.bind(currentList[position])
-
inner class FolderViewHolder(val binding: CardFolderBinding) :
- RecyclerView.ViewHolder(binding.root) {
- private lateinit var gameDir: GameDir
-
- fun bind(gameDir: GameDir) {
- this.gameDir = gameDir
-
+ AbstractViewHolder<GameDir>(binding) {
+ override fun bind(model: GameDir) {
binding.apply {
- path.text = Uri.parse(gameDir.uriString).path
+ path.text = Uri.parse(model.uriString).path
path.postDelayed(
{
path.isSelected = true
@@ -50,7 +38,7 @@ class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesVie
)
buttonEdit.setOnClickListener {
- GameFolderPropertiesDialogFragment.newInstance(this@FolderViewHolder.gameDir)
+ GameFolderPropertiesDialogFragment.newInstance(model)
.show(
activity.supportFragmentManager,
GameFolderPropertiesDialogFragment.TAG
@@ -58,19 +46,9 @@ class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesVie
}
buttonDelete.setOnClickListener {
- gamesViewModel.removeFolder(this@FolderViewHolder.gameDir)
+ gamesViewModel.removeFolder(model)
}
}
}
}
-
- private class DiffCallback : DiffUtil.ItemCallback<GameDir>() {
- override fun areItemsTheSame(oldItem: GameDir, newItem: GameDir): Boolean {
- return oldItem == newItem
- }
-
- override fun areContentsTheSame(oldItem: GameDir, newItem: GameDir): Boolean {
- return oldItem == newItem
- }
- }
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
index a578f0de8..e26c2e0ab 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
@@ -9,7 +9,6 @@ import android.graphics.drawable.LayerDrawable
import android.net.Uri
import android.text.TextUtils
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Toast
@@ -25,10 +24,6 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.preference.PreferenceManager
-import androidx.recyclerview.widget.AsyncDifferConfig
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -36,122 +31,26 @@ import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.activities.EmulationActivity
-import org.yuzu.yuzu_emu.adapters.GameAdapter.GameViewHolder
import org.yuzu.yuzu_emu.databinding.CardGameBinding
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.utils.GameIconUtils
+import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class GameAdapter(private val activity: AppCompatActivity) :
- ListAdapter<Game, GameViewHolder>(AsyncDifferConfig.Builder(DiffCallback()).build()),
- View.OnClickListener,
- View.OnLongClickListener {
+ AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameViewHolder {
- // Create a new view.
- val binding = CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
- binding.cardGame.setOnClickListener(this)
- binding.cardGame.setOnLongClickListener(this)
-
- // Use that view to create a ViewHolder.
- return GameViewHolder(binding)
- }
-
- override fun onBindViewHolder(holder: GameViewHolder, position: Int) =
- holder.bind(currentList[position])
-
- override fun getItemCount(): Int = currentList.size
-
- /**
- * Launches the game that was clicked on.
- *
- * @param view The card representing the game the user wants to play.
- */
- override fun onClick(view: View) {
- val holder = view.tag as GameViewHolder
-
- val gameExists = DocumentFile.fromSingleUri(
- YuzuApplication.appContext,
- Uri.parse(holder.game.path)
- )?.exists() == true
- if (!gameExists) {
- Toast.makeText(
- YuzuApplication.appContext,
- R.string.loader_error_file_not_found,
- Toast.LENGTH_LONG
- ).show()
-
- ViewModelProvider(activity)[GamesViewModel::class.java].reloadGames(true)
- return
- }
-
- val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
- preferences.edit()
- .putLong(
- holder.game.keyLastPlayedTime,
- System.currentTimeMillis()
- )
- .apply()
-
- val openIntent = Intent(YuzuApplication.appContext, EmulationActivity::class.java).apply {
- action = Intent.ACTION_VIEW
- data = Uri.parse(holder.game.path)
- }
-
- activity.lifecycleScope.launch {
- withContext(Dispatchers.IO) {
- val layerDrawable = ResourcesCompat.getDrawable(
- YuzuApplication.appContext.resources,
- R.drawable.shortcut,
- null
- ) as LayerDrawable
- layerDrawable.setDrawableByLayerId(
- R.id.shortcut_foreground,
- GameIconUtils.getGameIcon(activity, holder.game)
- .toDrawable(YuzuApplication.appContext.resources)
- )
- val inset = YuzuApplication.appContext.resources
- .getDimensionPixelSize(R.dimen.icon_inset)
- layerDrawable.setLayerInset(1, inset, inset, inset, inset)
- val shortcut =
- ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
- .setShortLabel(holder.game.title)
- .setIcon(
- IconCompat.createWithAdaptiveBitmap(
- layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
- )
- )
- .setIntent(openIntent)
- .build()
- ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
- }
- }
-
- val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game, true)
- view.findNavController().navigate(action)
- }
-
- override fun onLongClick(view: View): Boolean {
- val holder = view.tag as GameViewHolder
- val action = HomeNavigationDirections.actionGlobalPerGamePropertiesFragment(holder.game)
- view.findNavController().navigate(action)
- return true
+ CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ .also { return GameViewHolder(it) }
}
inner class GameViewHolder(val binding: CardGameBinding) :
- RecyclerView.ViewHolder(binding.root) {
- lateinit var game: Game
-
- init {
- binding.cardGame.tag = this
- }
-
- fun bind(game: Game) {
- this.game = game
-
+ AbstractViewHolder<Game>(binding) {
+ override fun bind(model: Game) {
binding.imageGameScreen.scaleType = ImageView.ScaleType.CENTER_CROP
- GameIconUtils.loadGameIcon(game, binding.imageGameScreen)
+ GameIconUtils.loadGameIcon(model, binding.imageGameScreen)
- binding.textGameTitle.text = game.title.replace("[\\t\\n\\r]+".toRegex(), " ")
+ binding.textGameTitle.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ")
binding.textGameTitle.postDelayed(
{
@@ -160,16 +59,79 @@ class GameAdapter(private val activity: AppCompatActivity) :
},
3000
)
+
+ binding.cardGame.setOnClickListener { onClick(model) }
+ binding.cardGame.setOnLongClickListener { onLongClick(model) }
}
- }
- private class DiffCallback : DiffUtil.ItemCallback<Game>() {
- override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean {
- return oldItem == newItem
+ fun onClick(game: Game) {
+ val gameExists = DocumentFile.fromSingleUri(
+ YuzuApplication.appContext,
+ Uri.parse(game.path)
+ )?.exists() == true
+ if (!gameExists) {
+ Toast.makeText(
+ YuzuApplication.appContext,
+ R.string.loader_error_file_not_found,
+ Toast.LENGTH_LONG
+ ).show()
+
+ ViewModelProvider(activity)[GamesViewModel::class.java].reloadGames(true)
+ return
+ }
+
+ val preferences =
+ PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
+ preferences.edit()
+ .putLong(
+ game.keyLastPlayedTime,
+ System.currentTimeMillis()
+ )
+ .apply()
+
+ val openIntent =
+ Intent(YuzuApplication.appContext, EmulationActivity::class.java).apply {
+ action = Intent.ACTION_VIEW
+ data = Uri.parse(game.path)
+ }
+
+ activity.lifecycleScope.launch {
+ withContext(Dispatchers.IO) {
+ val layerDrawable = ResourcesCompat.getDrawable(
+ YuzuApplication.appContext.resources,
+ R.drawable.shortcut,
+ null
+ ) as LayerDrawable
+ layerDrawable.setDrawableByLayerId(
+ R.id.shortcut_foreground,
+ GameIconUtils.getGameIcon(activity, game)
+ .toDrawable(YuzuApplication.appContext.resources)
+ )
+ val inset = YuzuApplication.appContext.resources
+ .getDimensionPixelSize(R.dimen.icon_inset)
+ layerDrawable.setLayerInset(1, inset, inset, inset, inset)
+ val shortcut =
+ ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
+ .setShortLabel(game.title)
+ .setIcon(
+ IconCompat.createWithAdaptiveBitmap(
+ layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
+ )
+ )
+ .setIntent(openIntent)
+ .build()
+ ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
+ }
+ }
+
+ val action = HomeNavigationDirections.actionGlobalEmulationActivity(game, true)
+ binding.root.findNavController().navigate(action)
}
- override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
- return oldItem == newItem
+ fun onLongClick(game: Game): Boolean {
+ val action = HomeNavigationDirections.actionGlobalPerGamePropertiesFragment(game)
+ binding.root.findNavController().navigate(action)
+ return true
}
}
}