绑定适配器,用于使用毕加索显示来自URL的图像

时间:2019-05-09 12:00:00

标签: android android-recyclerview android-adapter picasso android-databinding

我在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 :(得分:0)

修改
//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)
)

答案 1 :(得分:0)

我认为您应该指定如下的缓存机制:

Picasso.with(cardView.context)
.networkPolicy(OFFLINE, NO_CACHE)
.load(url)
.into(view)