mirror of https://git.suyu.dev/suyu/suyu
android: Create custom game icon loader
This commit is contained in:
parent
44bce11853
commit
270f430f70
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.adapters
|
package org.yuzu.yuzu_emu.adapters
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -15,23 +13,20 @@ import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import org.yuzu.yuzu_emu.adapters.GameAdapter.GameViewHolder
|
import org.yuzu.yuzu_emu.adapters.GameAdapter.GameViewHolder
|
||||||
import org.yuzu.yuzu_emu.databinding.CardGameBinding
|
import org.yuzu.yuzu_emu.databinding.CardGameBinding
|
||||||
import org.yuzu.yuzu_emu.model.Game
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
import org.yuzu.yuzu_emu.model.GamesViewModel
|
import org.yuzu.yuzu_emu.model.GamesViewModel
|
||||||
|
import org.yuzu.yuzu_emu.utils.GameIconUtils
|
||||||
|
|
||||||
class GameAdapter(private val activity: AppCompatActivity) :
|
class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
ListAdapter<Game, GameViewHolder>(AsyncDifferConfig.Builder(DiffCallback()).build()),
|
ListAdapter<Game, GameViewHolder>(AsyncDifferConfig.Builder(DiffCallback()).build()),
|
||||||
|
@ -98,12 +93,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
this.game = game
|
this.game = game
|
||||||
|
|
||||||
binding.imageGameScreen.scaleType = ImageView.ScaleType.CENTER_CROP
|
binding.imageGameScreen.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
activity.lifecycleScope.launch {
|
GameIconUtils.loadGameIcon(game, binding.imageGameScreen)
|
||||||
val bitmap = decodeGameIcon(game.path)
|
|
||||||
binding.imageGameScreen.load(bitmap) {
|
|
||||||
error(R.drawable.default_icon)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.textGameTitle.text = game.title.replace("[\\t\\n\\r]+".toRegex(), " ")
|
binding.textGameTitle.text = game.title.replace("[\\t\\n\\r]+".toRegex(), " ")
|
||||||
|
|
||||||
|
@ -126,14 +116,4 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
return oldItem == newItem
|
return oldItem == newItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decodeGameIcon(uri: String): Bitmap? {
|
|
||||||
val data = NativeLibrary.getIcon(uri)
|
|
||||||
return BitmapFactory.decodeByteArray(
|
|
||||||
data,
|
|
||||||
0,
|
|
||||||
data.size,
|
|
||||||
BitmapFactory.Options()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
|
import coil.ImageLoader
|
||||||
|
import coil.decode.DataSource
|
||||||
|
import coil.fetch.DrawableResult
|
||||||
|
import coil.fetch.FetchResult
|
||||||
|
import coil.fetch.Fetcher
|
||||||
|
import coil.key.Keyer
|
||||||
|
import coil.memory.MemoryCache
|
||||||
|
import coil.request.ImageRequest
|
||||||
|
import coil.request.Options
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
|
|
||||||
|
class GameIconFetcher(
|
||||||
|
private val game: Game,
|
||||||
|
private val options: Options
|
||||||
|
) : Fetcher {
|
||||||
|
override suspend fun fetch(): FetchResult {
|
||||||
|
return DrawableResult(
|
||||||
|
drawable = decodeGameIcon(game.path)!!.toDrawable(options.context.resources),
|
||||||
|
isSampled = false,
|
||||||
|
dataSource = DataSource.DISK
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decodeGameIcon(uri: String): Bitmap? {
|
||||||
|
val data = NativeLibrary.getIcon(uri)
|
||||||
|
return BitmapFactory.decodeByteArray(
|
||||||
|
data,
|
||||||
|
0,
|
||||||
|
data.size,
|
||||||
|
BitmapFactory.Options()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Factory : Fetcher.Factory<Game> {
|
||||||
|
override fun create(data: Game, options: Options, imageLoader: ImageLoader): Fetcher =
|
||||||
|
GameIconFetcher(data, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GameIconKeyer : Keyer<Game> {
|
||||||
|
override fun key(data: Game, options: Options): String = data.path
|
||||||
|
}
|
||||||
|
|
||||||
|
object GameIconUtils {
|
||||||
|
private val imageLoader = ImageLoader.Builder(YuzuApplication.appContext)
|
||||||
|
.components {
|
||||||
|
add(GameIconKeyer())
|
||||||
|
add(GameIconFetcher.Factory())
|
||||||
|
}
|
||||||
|
.memoryCache {
|
||||||
|
MemoryCache.Builder(YuzuApplication.appContext)
|
||||||
|
.maxSizePercent(0.25)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
|
||||||
|
fun loadGameIcon(game: Game, imageView: ImageView) {
|
||||||
|
val request = ImageRequest.Builder(YuzuApplication.appContext)
|
||||||
|
.data(game)
|
||||||
|
.target(imageView)
|
||||||
|
.error(R.drawable.default_icon)
|
||||||
|
.build()
|
||||||
|
imageLoader.enqueue(request)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue