滚动时图像在 recyclerview 中被替换,android?
Image gets replaced in recylerview while scrolling, android?
我在 recylerview 中显示国家列表及其旗帜
第一个元素没有图像并使用在页面启动时可见的默认图像
但是当我滚动并返回到它时,图像会从列表中随机更改为一些不应该发生的
这是我的适配器
class CountryAdapter(private val list: MutableList<Data?>?) :
RecyclerView.Adapter<CountryAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = ElementCountryBinding.inflate(inflater)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val country: Data? = list?.get(position)
if (country != null) {
holder.bind(country)
}
holder.itemView.setOnClickListener {
}
}
override fun getItemCount(): Int = list!!.size
inner class ViewHolder(val binding: ElementCountryBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(country: Data) {
binding.data = country
if (country.filePath != null)
Glide.with(binding.root.context)
.load(country.filePath!!.trim()).into(binding.ivFlag)
}
}
}
这是 xml 布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="data"
type="com.mountmeru.model.Data" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@+id/main_cardview"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginBottom="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_flag"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_marginStart="10dp"
android:adjustViewBounds="true"
android:src="@drawable/ic_share"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvCountryName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@{data.countryName}"
app:layout_constraintBottom_toBottomOf="@+id/iv_flag"
app:layout_constraintLeft_toRightOf="@+id/iv_flag"
app:layout_constraintTop_toTopOf="@+id/iv_flag" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
< /RelativeLayout>
</layout>
截图
由于 RV/LV 中视图的回收机制,这很正常。为避免将其设置为 null
if (country.filePath != null)
Glide.with(binding.root.context)
.load(country.filePath!!.trim()).into(binding.ivFlag)
else
binding.ivFlag.setImageDrawable(null)
假设 ivFlag
是 ImageView
,或者 default/placeholder 如果你有
发生这种情况是因为您从未在绑定视图期间设置 ic_share
。
inner class ViewHolder(val binding: ElementCountryBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(country: Data) {
binding.data = country
if(adapterPosition==0){
binding.ivFlag.setImageResource(R.drawable.binding.ivFlag)
}else {
if (country.filePath != null)
Glide.with(binding.root.context)
.load(country.filePath!!.trim()).into(binding.ivFlag)
}
}
}
所以您在 XML 布局中指定的默认图像是 ic_share,这意味着当调用 onBindViewHolder 时,图像被替换为:
.load(country.filePath!!.trim()).into(binding.ivFlag)
但是,您从未指定在位置 0 处,图标必须是 ic_share,因此由于 RecyclerView 的性质,当您向下和向上滚动并(再次)创建第一个 itemHolder 时,它使用回收的从更下方查看,并且由于您没有在位置 0 处将 ic_share 设置为 iv_flag,因此它仅使用回收的视图图像。
如果您只是在 bind 方法中添加像 @ADM 这样的建议代码行,如下所示:
if(adapterPosition==0){
binding.ivFlag.setImageResource(R.drawable.ic_share)
}
有了 ic_share,我认为应该可以正常工作
拥有函数 getItemViewType 也解决了问题
override fun getItemViewType(position: Int): Int {
return position
}
我在 recylerview 中显示国家列表及其旗帜 第一个元素没有图像并使用在页面启动时可见的默认图像 但是当我滚动并返回到它时,图像会从列表中随机更改为一些不应该发生的
这是我的适配器
class CountryAdapter(private val list: MutableList<Data?>?) :
RecyclerView.Adapter<CountryAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = ElementCountryBinding.inflate(inflater)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val country: Data? = list?.get(position)
if (country != null) {
holder.bind(country)
}
holder.itemView.setOnClickListener {
}
}
override fun getItemCount(): Int = list!!.size
inner class ViewHolder(val binding: ElementCountryBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(country: Data) {
binding.data = country
if (country.filePath != null)
Glide.with(binding.root.context)
.load(country.filePath!!.trim()).into(binding.ivFlag)
}
}
}
这是 xml 布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="data"
type="com.mountmeru.model.Data" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@+id/main_cardview"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginBottom="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_flag"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_marginStart="10dp"
android:adjustViewBounds="true"
android:src="@drawable/ic_share"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvCountryName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@{data.countryName}"
app:layout_constraintBottom_toBottomOf="@+id/iv_flag"
app:layout_constraintLeft_toRightOf="@+id/iv_flag"
app:layout_constraintTop_toTopOf="@+id/iv_flag" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
< /RelativeLayout>
</layout>
截图
由于 RV/LV 中视图的回收机制,这很正常。为避免将其设置为 null
if (country.filePath != null)
Glide.with(binding.root.context)
.load(country.filePath!!.trim()).into(binding.ivFlag)
else
binding.ivFlag.setImageDrawable(null)
假设 ivFlag
是 ImageView
,或者 default/placeholder 如果你有
发生这种情况是因为您从未在绑定视图期间设置 ic_share
。
inner class ViewHolder(val binding: ElementCountryBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(country: Data) {
binding.data = country
if(adapterPosition==0){
binding.ivFlag.setImageResource(R.drawable.binding.ivFlag)
}else {
if (country.filePath != null)
Glide.with(binding.root.context)
.load(country.filePath!!.trim()).into(binding.ivFlag)
}
}
}
所以您在 XML 布局中指定的默认图像是 ic_share,这意味着当调用 onBindViewHolder 时,图像被替换为:
.load(country.filePath!!.trim()).into(binding.ivFlag)
但是,您从未指定在位置 0 处,图标必须是 ic_share,因此由于 RecyclerView 的性质,当您向下和向上滚动并(再次)创建第一个 itemHolder 时,它使用回收的从更下方查看,并且由于您没有在位置 0 处将 ic_share 设置为 iv_flag,因此它仅使用回收的视图图像。
如果您只是在 bind 方法中添加像 @ADM 这样的建议代码行,如下所示:
if(adapterPosition==0){
binding.ivFlag.setImageResource(R.drawable.ic_share)
}
有了 ic_share,我认为应该可以正常工作
拥有函数 getItemViewType 也解决了问题
override fun getItemViewType(position: Int): Int {
return position
}