Android: SVG Drawables перестают работать или дают сбой в списках RecyclerView - PullRequest
0 голосов
/ 05 мая 2020

У меня возникла проблема, когда я импортировал некоторые чертежи SVG (которые оптимизированы в Illustrator и имеют данные короткого пути, поэтому их сложность не обсуждается) и отобразил их в элементах RecyclerView. Проблема в том, что после многократного тестирования приложения они перестают работать или начинают рендеринг с ошибками (например, отсутствием фрагментов или фигур). Как ни странно, очистка кеша приложений решает проблему, и они работают нормально до тех пор, пока я не запустил приложение из Android Studio примерно 5-6 раз.

Вот что я имею в виду под «перестал работать»: enter image description here

enter image description here

В одном действии они отображаются как красные предупреждения, в другом они появляются как значок отпечатка пальца (хотя я нет такого значка во всем проекте и реализации отпечатка пальца).

Вот реализация:

Я добавляю записи в базу данных комнаты следующим образом:

Category(icon = R.drawable.ic_category_homepage)

где класс данных категории выглядит следующим образом:

@Entity(tableName = "categories")
data class Category(
  val title: String,
  @DrawableRes
  val icon: Int
)

Итак, я добавляю ссылку на SVG для рисования как DrawableRes Int в локальном хранилище. Затем, когда я показываю значок в адаптере, я использую Glide:

        Glide.with(context)
          .load(category.icon)
          .transition(DrawableTransitionOptions.withCrossFade())
          .into(itemView.categoryIV)

Вот весь адаптер:

class DrawerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private val categories: ArrayList<Category> = ArrayList()

fun submitCategories(newFeed: List<Category>, lifecycleCoroutineScope: LifecycleCoroutineScope) {
    lifecycleCoroutineScope.launch {
        val result = coroutineRunOnComputationThread {
            val oldFeed = categories
            val result: DiffUtil.DiffResult = DiffUtil.calculateDiff(
                DrawerDiffCallback(oldFeed, newFeed)
            )
            categories.clear()
            categories.addAll(newFeed)
            result
        }
        coroutineRunOnMainThread {
            result.dispatchUpdatesTo(this@DrawerAdapter)
        }
    }
}

override fun getItemCount(): Int = categories.size
override fun getItemId(position: Int): Long {
    return if (categories.isNullOrEmpty()) 0 else categories[position].id
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    return DrawerItemViewHolder(parent.inflate(R.layout.item_drawer_menu))
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
    (holder as DrawerItemViewHolder).bind(categories[position])

inner class DrawerItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(category: Category) = with(itemView) {
        Glide.with(context)
            .load(category.icon)
            .transition(DrawableTransitionOptions.withCrossFade())
            .into(itemDrawerIVIcon)

        if (category.preConfigured && category.resTitle != null)
            itemDrawerTVTitle.text = context.resources.getString(category.resTitle)
        else
            itemDrawerTVTitle.text = category.title
    }
}

private inner class DrawerDiffCallback(
    private var oldFeed: List<Category>,
    private var newFeed: List<Category>
) : DiffUtil.Callback() {
    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        val oldItem = oldFeed[oldItemPosition]
        val newItem = newFeed[newItemPosition]
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        val oldItem = oldFeed[oldItemPosition]
        val newItem = newFeed[newItemPosition]
        return oldItem == newItem
    }

    override fun getOldListSize(): Int = oldFeed.size
    override fun getNewListSize(): Int = newFeed.size
}

}

Любая идея почему у меня такое странное поведение?

1 Ответ

0 голосов
/ 05 мая 2020

Надеюсь, это решит вашу проблему с ошибками.

Picasso.get().load(category.icon)
            .error(R.drawable.placeholder_round)
            .placeholder(R.drawable.placeholder_round)
            .resize(100, 100)
            .into(itemDrawerIVIcon)

Просто замените Glide на Picasso с приведенной выше конфигурацией

...