Связывающий адаптер, используемый для отображения изображений с URL-адреса с помощью Picasso - PullRequest
0 голосов
/ 09 мая 2019

У меня есть проект в Github: https://github.com/Ali-Rezaei/News-Cache

Включает в себя следующий адаптер привязки:

@BindingAdapter("imageUrl")
fun bindImage(cardView: CardView, url: String) {

    val imageView: ImageView = cardView.findViewById(R.id.article_poster)
    Picasso.with(cardView.context).load(url).into(
        imageView,
        PicassoPalette.with(url, imageView)
            .use(PicassoPalette.Profile.VIBRANT)
            .intoBackground(cardView.findViewById(R.id.article_background), PicassoPalette.Swatch.RGB)
            .intoTextColor(cardView.findViewById(R.id.article_name), PicassoPalette.Swatch.BODY_TEXT_COLOR)
    )
}

А это мой NewsAdapter:

class NewsAdapter : ListAdapter<Article, NewsAdapter.NewsViewHolder>(DiffCallback) {

    /**
     * Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
     * an item.
     */
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = NewsViewHolder.from(parent)

    /**
     * Called by RecyclerView to display the data at the specified position. This method should
     * update the contents of the {@link ViewHolder#itemView} to reflect the item at the given
     * position.
     */
    override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
        holder.bind(getItem(position))
    }

    /**
     * ViewHolder for News items. All work is done by data binding.
     */
    class NewsViewHolder(val binding: NewsItemBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(news: Article) {
            with(binding) {
                article = news
                executePendingBindings()
            }
        }

        companion object {
            fun from(parent: ViewGroup): NewsViewHolder {
                val binding = NewsItemBinding.inflate(
                    parent.context.layoutInflater,
                    parent,
                    false
                )
                return NewsViewHolder(binding)
            }
        }
    }

    /**
     * Allows the RecyclerView to determine which items have changed when the [List] of [Article]
     * has been updated.
     */
    companion object DiffCallback : DiffUtil.ItemCallback<Article>() {
        override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean {
            return oldItem.url == newItem.url
        }
    }
}

Это мои LiveData, которые наблюдаются во фрагменте:

viewModel.news.observe(viewLifecycleOwner, Observer<List<Article>> { articles ->
            articles?.apply {
                viewModelAdapter?.submitList(articles)
            }
        })

А вот как я настраиваю адаптер recyclerView:

viewModelAdapter = NewsAdapter()

        with(binding) {
            recyclerView.apply {
                addItemDecoration(MarginDecoration(context))
                setHasFixedSize(true)
                adapter = viewModelAdapter
            }
        }

По какой-то причине, когда я прокручиваю recyclerView до конца и возвращаюсь к началу, он начинает снова загружать изображения. Я ожидаю, что это будет кэшировано. В чем моя ошибка?

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Я думаю, вы должны указать механизм кэширования следующим образом:

Picasso.with(cardView.context)
.networkPolicy(OFFLINE, NO_CACHE)
.load(url)
.into(view)
0 голосов
/ 09 мая 2019

Измените его с помощью

//10MB Cache
Picasso picasso =  new Picasso
    .Builder(this)
    .downloader(new OkHttpDownloader(getCacheDir(), 10000000))
    .build();

Создайте этот экземпляр при запуске приложения и используйте этот экземпляр без воссоздания.

picasso.with(cardView.context).load(url).networkPolicy(NetworkPolicy.OFFLINE).into(
    imageView,
    PicassoPalette.with(url, imageView)
        .use(PicassoPalette.Profile.VIBRANT)
        .intoBackground(cardView.findViewById(R.id.article_background), PicassoPalette.Swatch.RGB)
        .intoTextColor(cardView.findViewById(R.id.article_name), PicassoPalette.Swatch.BODY_TEXT_COLOR)
)
...