如何从Adapter动态修改RecyclerView中ImageView的图片?
问题描述
我卡了好几个小时了,想在RecyclerView的Adapter中修改ImageView的图片,图片名称来自Firebase(对应Model中的Time字段),图片存放在res\drawable目录下。我是Kotlin和Android开发新手,求帮忙或者教程指引。
相关代码
主活动代码
private fun getDataFromFirebase(){ binding.progressBar.visibility = View.VISIBLE FirebaseDatabase.getInstance("firebaseurl").reference .get() .addOnSuccessListener { dataSnapshot-> if(dataSnapshot.exists()){ for (snapshot in dataSnapshot.children){ val quizModel = snapshot.getValue(QuizModel::class.java) if (quizModel != null) { quizModelList.add(quizModel) } } } setupRecyclerView() } }
Adapter代码
package np.com.bimalkafle.quizonline import android.content.Intent import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import np.com.bimalkafle.quizonline.databinding.QuizItemRecyclerRowBinding class QuizListAdapter(private val quizModelList : List<QuizModel>) : RecyclerView.Adapter<QuizListAdapter.MyViewHolder>() { class MyViewHolder(private val binding: QuizItemRecyclerRowBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(model : QuizModel){ binding.apply { quizTitleText.text = model.title quizSubtitleText.text = model.subtitle quizTimeText.text = model.time + " min" quizImage.setImageResource(R.drawable.humanas) root.setOnClickListener { val intent = Intent(root.context,QuizActivity::class.java) QuizActivity.questionModelList = model.questionList QuizActivity.time = model.time root.context.startActivity(intent) } } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val binding = QuizItemRecyclerRowBinding.inflate(LayoutInflater.from(parent.context),parent,false) return MyViewHolder(binding) } override fun getItemCount(): Int { return quizModelList.size } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.bind(quizModelList[position]) } }
布局代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg" android:orientation="vertical" android:padding="16dp" tools:context=".MainActivity"> <ImageView android:layout_width="match_parent" android:layout_height="160dp" android:src="@drawable/logo" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:background="@drawable/rounded_corner" android:backgroundTint="@color/blueblack" android:orientation="vertical" android:padding="8dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:letterSpacing="0.1" android:text="Passei no Encceja" android:textColor="@color/white" android:textSize="34sp" android:textStyle="bold" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" android:gravity="center" android:text="Vamos estudar jogando juntos" android:textColor="@color/white" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:layout_marginTop="16dp" android:text="Todas as Disciplinas" android:textSize="20sp" android:textStyle="bold" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ProgressBar android:id="@+id/progress_bar" android:layout_width="20dp" android:layout_height="20dp" android:layout_centerInParent="true" android:visibility="gone" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" /> </RelativeLayout> </LinearLayout>
解决方案
核心思路是通过Firebase返回的图片名称(即model.time),动态获取对应的drawable资源ID,再设置给ImageView。
修改Adapter的bind方法
把原代码中quizImage.setImageResource(R.drawable.humanas)替换为以下代码:
binding.apply { // 其他原有代码保持不变... val context = root.context // 根据图片名称获取drawable资源ID val imageResId = context.resources.getIdentifier( model.time, "drawable", context.packageName ) // 检查资源是否存在,避免App崩溃 if (imageResId != 0) { quizImage.setImageResource(imageResId) } else { // 设置默认占位图(需提前在drawable目录添加对应资源) quizImage.setImageResource(R.drawable.default_placeholder) } // 点击事件原有代码保持不变... }
关键注意事项
- 文件名严格匹配:Android的drawable资源文件名仅支持小写字母、数字、下划线和连字符,Firebase中
time字段的值必须和文件名完全一致(比如Firebase存"humanas",drawable里对应humanas.png或humanas.xml) - 默认图兜底:如果Firebase返回的名称找不到对应资源,一定要设置默认图,防止App崩溃
- 资源命名规范:不要用特殊字符或大写字母命名drawable资源,否则会导致无法获取到资源ID
内容的提问来源于stack exchange,提问作者Alexandre Leitão
相关产品推荐
相关产品推荐

