如何使用kotlin在RecyclerView.ViewHolder中绑定视图

令我困惑的是如何在Recycleler.ViewHolder绑定视图。 这是我简单的适配器,如何将它转换为kotlin使用kotlin-android-extensions没有ButterKnife

 public class RoomAdapter extends RecyclerView.Adapter<ViewHolder> { private OnItemClickListener mListener; private List<LocationBean> mRooms; static class ViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.tv_title) TextView tvTitle; public ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } } public void setData(List<LocationBean> rooms) { mRooms = rooms; notifyDataSetChanged(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_first_select, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.tvTitle.setText(mRooms.get(position).getLocation()); holder.itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mListener.onItemClickListener(v, holder.getLayoutPosition()); } }); } @Override public int getItemCount() { return mRooms == null ? 0 : mRooms.size(); } public void setOnItemClickListener(OnItemClickListener listener) { mListener = listener; } public interface OnItemClickListener { void onItemClickListener(View v, int pos); } } 

发布的解决方案工作,但我想添加一些东西。 viewholder模式的目的是只为每个视图调用一次代价高的findViewById ,然后在ViewHolder保存这些引用,并在需要绑定的时候从那里访问视图。

然而,在onBindViewHolder方法中调用holder.itemView.tv_title.text将导致findViewById调用在每次绑定View时在itemView中查找具有id tv_titleView 。 这基本上消除了视图持有者的性能收益和缓存理念。

您可以同时使用视图模式和Kotlin Android扩展,方法是向ViewHolder添加一个属性,然后使用扩展名进行初始化,如下所示:

 class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val title = itemView.tv_title } 

然后你可以通过这个属性访问View

 override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.title.text = mRooms!!.get(position).getLocation() holder.itemView.setOnClickListener { v -> mListener?.onItemClickListener(v, holder.layoutPosition) } } 

最后,我建议摆脱!! 运算符,并执行空检查,而不是:

 mRooms?.let { rooms -> holder.title.text = rooms[position].getLocation() } 

只要确保在应用程序gradle文件(而不是您的根gradle)中apply plugin: 'kotlin-android-extensions' ,然后使用转换Java文件到Kotlin文件快捷方式。 删除Butterknife代码并直接引用您的ViewHolder对象中的ViewHolder像这样

 import kotlinx.android.synthetic.main.item_first_select.view.* class RoomAdapter : RecyclerView.Adapter<RoomAdapter.ViewHolder>() { private var mListener: OnItemClickListener? = null private var mRooms: List<LocationBean>? = null class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) fun setData(rooms: List<LocationBean>) { mRooms = rooms notifyDataSetChanged() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_first_select, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.itemView.tv_title.text = mRooms!!.get(position).getLocation() holder.itemView.setOnClickListener { v -> mListener?.onItemClickListener(v, holder.layoutPosition) } } override fun getItemCount(): Int { return mRooms?.size ?: 0 } fun setOnItemClickListener(listener: OnItemClickListener) { mListener = listener } interface OnItemClickListener { fun onItemClickListener(v: View, pos: Int) } } 

其他人很好地回答了这个问题,我只是想在class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) itemView)在itemView之后应该没有可为null的操作符(' ? ')以便kotlin绑定工作。

使用自动完成从ViewHolder(itemView)添加构造参数时,Android Studio会自动添加可空操作符。