Improve icon display when selecting apps for restore
This commit is contained in:
parent
787b9346a8
commit
eecfcdb285
4 changed files with 27 additions and 24 deletions
|
@ -1,6 +1,6 @@
|
|||
package com.stevesoltys.seedvault.restore
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.format.DateUtils
|
||||
import android.text.format.Formatter
|
||||
import android.view.LayoutInflater
|
||||
|
@ -39,7 +39,7 @@ internal data class SelectableAppItem(
|
|||
|
||||
internal class AppSelectionAdapter(
|
||||
val scope: CoroutineScope,
|
||||
val iconLoader: suspend (SelectableAppItem, (Bitmap) -> Unit) -> Unit,
|
||||
val iconLoader: suspend (SelectableAppItem, (Drawable) -> Unit) -> Unit,
|
||||
val listener: (SelectableAppItem) -> Unit,
|
||||
) : Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
|
@ -156,16 +156,18 @@ internal class AppSelectionAdapter(
|
|||
checkBox.visibility = if (item.hasIcon == null) INVISIBLE else VISIBLE
|
||||
progressBar.visibility = if (item.hasIcon == null) VISIBLE else INVISIBLE
|
||||
|
||||
val isSpecial = item.metadata.isInternalSystem
|
||||
appIcon.scaleType = FIT_CENTER
|
||||
appIcon.setImageResource(R.drawable.ic_launcher_default)
|
||||
if (item.hasIcon == null) {
|
||||
appIcon.scaleType = if (isSpecial) CENTER else FIT_CENTER
|
||||
if (item.hasIcon == null && !isSpecial) {
|
||||
appIcon.alpha = 0.5f
|
||||
} else if (item.hasIcon) {
|
||||
} else if (item.hasIcon == true || isSpecial) {
|
||||
appIcon.alpha = 0.5f
|
||||
iconJob = scope.launch {
|
||||
iconLoader(item) { bitmap ->
|
||||
val isSpecial = item.metadata.system && !item.metadata.isLaunchableSystemApp
|
||||
appIcon.scaleType = if (isSpecial) CENTER else FIT_CENTER
|
||||
appIcon.setImageBitmap(bitmap)
|
||||
appIcon.setImageDrawable(bitmap)
|
||||
appIcon.alpha = 1f
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.stevesoltys.seedvault.restore
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -73,7 +73,7 @@ class AppSelectionFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun loadIcon(item: SelectableAppItem, callback: (Bitmap) -> Unit) {
|
||||
private suspend fun loadIcon(item: SelectableAppItem, callback: (Drawable) -> Unit) {
|
||||
viewModel.loadIcon(item, callback)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,14 +13,13 @@ import android.app.backup.IRestoreObserver
|
|||
import android.app.backup.IRestoreSession
|
||||
import android.app.backup.RestoreSet
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.RemoteException
|
||||
import android.os.UserHandle
|
||||
import android.util.Log
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.asLiveData
|
||||
|
@ -199,7 +198,7 @@ internal class RestoreViewModel(
|
|||
?: return@mapNotNull null
|
||||
if (metadata.time == 0L && !metadata.hasApk()) return@mapNotNull null
|
||||
val name = app.getString(data.nameRes)
|
||||
SelectableAppItem(packageName, metadata.copy(name = name), true, hasIcon = true)
|
||||
SelectableAppItem(packageName, metadata.copy(name = name), true)
|
||||
}
|
||||
val systemItem = SelectableAppItem(
|
||||
packageName = PACKAGE_NAME_SYSTEM,
|
||||
|
@ -227,10 +226,10 @@ internal class RestoreViewModel(
|
|||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error loading icons:", e)
|
||||
emptySet()
|
||||
}
|
||||
} + systemData.keys + setOf(PACKAGE_NAME_SYSTEM)
|
||||
// update state, so it knows that icons have loaded
|
||||
val updatedItems = items.map { item ->
|
||||
item.copy(hasIcon = item.hasIcon ?: false || item.packageName in packagesWithIcons)
|
||||
item.copy(hasIcon = item.packageName in packagesWithIcons)
|
||||
}
|
||||
val newState =
|
||||
SelectedAppsState(updatedItems, allSelected = true, iconsLoaded = true)
|
||||
|
@ -239,13 +238,13 @@ internal class RestoreViewModel(
|
|||
mDisplayFragment.setEvent(SELECT_APPS)
|
||||
}
|
||||
|
||||
suspend fun loadIcon(item: SelectableAppItem, callback: (Bitmap) -> Unit) {
|
||||
suspend fun loadIcon(item: SelectableAppItem, callback: (Drawable) -> Unit) {
|
||||
if (item.packageName == PACKAGE_NAME_SYSTEM) {
|
||||
val bitmap = getDrawable(app, R.drawable.ic_app_settings)!!.toBitmap()
|
||||
callback(bitmap)
|
||||
val drawable = getDrawable(app, R.drawable.ic_app_settings)!!
|
||||
callback(drawable)
|
||||
} else if (item.metadata.isInternalSystem && item.packageName in systemData.keys) {
|
||||
val bitmap = getDrawable(app, systemData[item.packageName]!!.iconRes)!!.toBitmap()
|
||||
callback(bitmap)
|
||||
val drawable = getDrawable(app, systemData[item.packageName]!!.iconRes)!!
|
||||
callback(drawable)
|
||||
} else {
|
||||
iconManager.loadIcon(item.packageName, callback)
|
||||
}
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
package com.stevesoltys.seedvault.worker
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Bitmap.CompressFormat.WEBP_LOSSY
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.Log
|
||||
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.transport.backup.PackageService
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -92,23 +93,24 @@ internal class IconManager(
|
|||
}
|
||||
|
||||
private val defaultIcon by lazy {
|
||||
getDrawable(context, R.drawable.ic_launcher_default)!!.toBitmap()
|
||||
getDrawable(context, R.drawable.ic_launcher_default)!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the icons for the given [packageName]
|
||||
* that was downloaded before with [downloadIcons].
|
||||
* Calls [callback] on the UiThread with the loaded [Bitmap] or the default icon.
|
||||
* Calls [callback] on the UiThread with the loaded [Drawable] or the default icon.
|
||||
*/
|
||||
suspend fun loadIcon(packageName: String, callback: (Bitmap) -> Unit) {
|
||||
suspend fun loadIcon(packageName: String, callback: (Drawable) -> Unit) {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
val folder = File(context.cacheDir, CACHE_FOLDER)
|
||||
val file = File(folder, packageName)
|
||||
file.inputStream().use { inputStream ->
|
||||
val bitmap = BitmapFactory.decodeStream(inputStream)
|
||||
val drawable =
|
||||
BitmapFactory.decodeStream(inputStream).toDrawable(context.resources)
|
||||
withContext(Dispatchers.Main) {
|
||||
callback(bitmap)
|
||||
callback(drawable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue