Android Studio Kotlin中RecyclerView如何根据对象特征实现多类型视图——以Rick and Morty API角色状态区分卡片为例
没问题!这事儿用RecyclerView的getItemViewType()完全能搞定,我给你一步步调整代码:
第一步:定义视图类型常量 & 重写getItemViewType()
先在你的Adapter里加两个常量标记不同视图类型,然后重写getItemViewType()方法,根据角色的status返回对应类型:
class Adapter(val characterList: List<Result>): RecyclerView.Adapter<RecyclerView.ViewHolder>() { // 定义视图类型常量 companion object { private const val VIEW_TYPE_ALIVE = 0 private const val VIEW_TYPE_DEAD = 1 } override fun getItemViewType(position: Int): Int { return when(characterList[position].status) { "Alive" -> VIEW_TYPE_ALIVE "Dead" -> VIEW_TYPE_DEAD else -> VIEW_TYPE_ALIVE // 其他状态默认用Alive的卡片 } } // 其他方法后续修改 }
第二步:创建对应两种布局的ViewHolder
你已经有默认的carditem蓝色背景布局,假设红色背景的布局叫carditem_dead,我们需要两个ViewHolder类来分别对应:
// 对应Alive角色的默认蓝色卡片 class AliveViewHolder(container: ViewGroup) : RecyclerView.ViewHolder( LayoutInflater.from(container.context).inflate(R.layout.carditem, container, false) ) { val crdView: CardView = itemView.findViewById(R.id.cardview1) val profileLink: ImageView = itemView.findViewById(R.id.imgProfilePhoto) val txtname: TextView = itemView.findViewById(R.id.name) val txtlocation: TextView = itemView.findViewById(R.id.location) val txtstatus: TextView = itemView.findViewById(R.id.status) fun bind(characterItem: Result) { txtname.text = characterItem.name profileLink.load(characterItem.image) txtlocation.text = characterItem.location.name txtstatus.text = characterItem.status } } // 对应Dead角色的红色背景卡片 class DeadViewHolder(container: ViewGroup) : RecyclerView.ViewHolder( LayoutInflater.from(container.context).inflate(R.layout.carditem_dead, container, false) ) { // 注意要和你的carditem_dead布局里的控件id对应 val crdView: CardView = itemView.findViewById(R.id.cardview_dead) val profileLink: ImageView = itemView.findViewById(R.id.imgProfilePhoto_dead) val txtname: TextView = itemView.findViewById(R.id.name_dead) val txtlocation: TextView = itemView.findViewById(R.id.location_dead) val txtstatus: TextView = itemView.findViewById(R.id.status_dead) fun bind(characterItem: Result) { txtname.text = characterItem.name profileLink.load(characterItem.image) txtlocation.text = characterItem.location.name txtstatus.text = characterItem.status // 也可以直接在这里设置背景色,不用单独布局:crdView.setCardBackgroundColor(Color.RED) } }
小贴士:如果两个布局的控件id完全一致,其实可以不用写两个ViewHolder,只需要在加载布局时根据viewType选对应xml就行,但分开写更清晰,后期维护也方便。
第三步:修改Adapter的onCreateViewHolder和onBindViewHolder
让Adapter根据不同viewType创建对应ViewHolder,并绑定数据:
class Adapter(val characterList: List<Result>): RecyclerView.Adapter<RecyclerView.ViewHolder>() { // 上面的常量和getItemViewType方法不变 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when(viewType) { VIEW_TYPE_ALIVE -> AliveViewHolder(parent) VIEW_TYPE_DEAD -> DeadViewHolder(parent) else -> AliveViewHolder(parent) } } override fun getItemCount(): Int { return characterList.size } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val character = characterList[position] when(holder) { is AliveViewHolder -> holder.bind(character) is DeadViewHolder -> holder.bind(character) } } }
最后检查
确保你的红色背景布局carditem_dead已创建,控件id和ViewHolder里的对应上(或者直接在DeadViewHolder里设置卡片背景色,不用额外布局)。这样运行后,Alive角色会显示蓝色默认卡片,Dead角色会显示红色专属卡片啦!
内容的提问来源于stack exchange,提问作者CSS
相关产品推荐
相关产品推荐

