如何从服务器加载图像到Recyclerview

问题描述 投票:0回答:1

我真的需要这个帮助,为什么不帮助我呢? :(

在我的应用程序中,我想使用嵌套

recyclerviews

其中一个
Recyclerview
用于显示数据列表,另一个 Recyclerview 应显示图像列表。
如下图:

我有一个奇怪的问题!
当我的图像超过一张时,复制一张图像并替换为其他图像!

为了显示来自服务器的图像,服务器发送给我base64,我对其进行解码,然后显示到适配器中。

我的显示列表适配器代码:

class TestsListAdapterSimple(val items: List<Result>) : RecyclerView.Adapter<TestsListAdapterSimple.ViewHolder>() {

    private lateinit var context: Context

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val binding = ItemTestHistoryBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        context = parent.context
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(items[position])
        holder.setIsRecyclable(false)
    }

    override fun getItemCount() = items.size

    inner class ViewHolder(private val binding: ItemTestHistoryBinding) : RecyclerView.ViewHolder(binding.root) {
        @SuppressLint("SetTextI18n", "CheckResult")
        fun bind(item: Result) {
            binding.apply {
                if (item.files != null) {
                    if (item.files.isNotEmpty()) {
                        val imagesAdapter = ImagesAdapterSimple(item.files.toMutableList(), context)
                        //imagesAdapter.setData(item.files)
                        avatarImg.apply {
                            addItemDecoration(OverlapRecyclerViewDecoration(3, -100))
                            layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
                            setHasFixedSize(true)
                            adapter = imagesAdapter
                        }
                    }
                }
                //Click
                binding.root.setOnClickListener {
                    onItemClickListener?.let {
                        it(item)
                    }
                }
            }
        }
    }

    private var onItemClickListener: ((Result) -> Unit)? = null

    fun setOnItemClickListener(listener: (Result) -> Unit) {
        onItemClickListener = listener
    }
}

我的显示图像适配器代码:

class ImagesAdapterSimple(val items: MutableList<File>, val context: Context) :
    RecyclerView.Adapter<ImagesAdapterSimple.ViewHolder>() {

    private val userToken by lazy { GoodPrefs.getInstance().getString(USER_TOKEN, "") }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImagesAdapterSimple.ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = ItemCircleImagesBinding.inflate(inflater, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ImagesAdapterSimple.ViewHolder, position: Int) {
        holder.bind()
        holder.setIsRecyclable(false)
    }

    override fun getItemCount() = if (items.size > 2) 3 else 1

    inner class ViewHolder(private val binding: ItemCircleImagesBinding) : RecyclerView.ViewHolder(binding.root) {
        @SuppressLint("CheckResult")
        fun bind() {
            binding.apply {
                items.forEach { item ->
                    avatarLoading.visibility = View.VISIBLE
                    ApiClient.getInstance().apisUseCase().getAvatarImage(userToken, item.id!!)
                        .applyIoScheduler()
                        .subscribe({
                            avatarLoading.visibility = View.GONE
                            if (it.isSuccessful) {
                                if (it.code() == 200) {
                                    if (it.body() != null) {
                                        val decodedBytes: ByteArray = Base64.decode(it.body()!!.data!!.file, Base64.DEFAULT)
                                        avatarImg.load(decodedBytes)
                                    }
                                }
                            }
                        }, {
                            avatarLoading.visibility = View.GONE
                        })
                }
            }
        }
    }
}

我该如何修复它?

java android kotlin android-recyclerview
1个回答
0
投票

您面临的问题似乎是嵌套 RecyclerView 中的所有项目重复使用相同的图像,而不是为每个项目显示不同的图像。发生这种情况是因为您正在迭代

bind()
ImagesAdapterSimple
方法中的所有项目,该方法为每个项目加载相同的图像。

要解决此问题,您需要确保

ImagesAdapterSimple
中的每个项目都与唯一的图像文件关联。您可以通过将图像文件直接传递到
ViewHolder
而不是迭代所有项目来实现此目的。以下是修改您的
ImagesAdapterSimple
:

的方法
class ImagesAdapterSimple(val items: MutableList<File>, val context: Context) :
    RecyclerView.Adapter<ImagesAdapterSimple.ViewHolder>() {

    private val userToken by lazy { GoodPrefs.getInstance().getString(USER_TOKEN, "") }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImagesAdapterSimple.ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = ItemCircleImagesBinding.inflate(inflater, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ImagesAdapterSimple.ViewHolder, position: Int) {
        val item = items[position]
        holder.bind(item)
        holder.setIsRecyclable(false)
    }

    override fun getItemCount() = if (items.size > 2) 3 else items.size

    inner class ViewHolder(private val binding: ItemCircleImagesBinding) : RecyclerView.ViewHolder(binding.root) {
        @SuppressLint("CheckResult")
        fun bind(item: File) {
            binding.apply {
                avatarLoading.visibility = View.VISIBLE
                ApiClient.getInstance().apisUseCase().getAvatarImage(userToken, item.id!!)
                    .applyIoScheduler()
                    .subscribe({
                        avatarLoading.visibility = View.GONE
                        if (it.isSuccessful) {
                            if (it.code() == 200) {
                                if (it.body() != null) {
                                    val decodedBytes: ByteArray = Base64.decode(it.body()!!.data!!.file, Base64.DEFAULT)
                                    avatarImg.load(decodedBytes)
                                }
                            }
                        }
                    }, {
                        avatarLoading.visibility = View.GONE
                    })
            }
        }
    }
}

通过此修改,

ViewHolder
中的每个
ImagesAdapterSimple
负责加载与
items
列表中相应项目关联的唯一图像。

确保将正确的

File
对象传递给适配器的
ViewHolder
方法中的
onBindViewHolder()
。这应该可以解决所有项目重复相同图像的问题。

© www.soinside.com 2019 - 2024. All rights reserved.