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

时间:2017-05-26 02:13:09

标签: android kotlin

让我困惑的是如何在Recycleler.ViewHolder中绑定视图。 这是我的简单适配器以及如何将其转换为使用kotlin-android-extensions而不使用ButterKnife的kotlin?

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);
  }

}

3 个答案:

答案 0 :(得分:43)

posted solution有效,但我想在其中添加内容。视图模式的目的是仅对每个视图进行一次昂贵的findViewById调用,然后将这些引用保存在ViewHolder内,并在需要绑定视图时从那里访问视图。 / p>

但是,在holder.itemView.tv_title.text方法中调用onBindViewHolder会导致findViewById调用,以便在{{1}内找到标识为View的{​​{1}}每次视图符号绑定时。这基本上消除了观看者所要求的性能提升和缓存理念。

您可以通过向tv_title添加属性,并使用扩展程序调用初始化它来同时使用视图集模式和Kotlin Android Extensions,如下所示:

itemView

然后您可以通过此属性访问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)
    }
}

答案 1 :(得分:8)

只需确保您的应用程序gradle文件中有val title = itemView.tv_title(不是您的根gradle),然后只需使用Convert Java文件转换为Kotlin文件快捷方式。删除Butterknife代码并直接引用import kotlinx.android.synthetic.main.item_first_select.view.* class RoomAdapter : RecyclerView.Adapter<RoomAdapter.ViewHolder>() { private var listener: OnItemClickListener? = null private var rooms: List<LocationBean>? = null class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(room: Room) { itemView.tv_title.text = room.getLocation() } } fun setData(rooms: List<LocationBean>) { this.rooms = 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) { rooms?.get(position)?.let { room -> holder.bind(room) } holder.itemView.setOnClickListener { v -> listener?.onItemClickListener(v, holder.layoutPosition) } } override fun getItemCount(): Int { return rooms?.size ?: 0 } fun setOnItemClickListener(listener: OnItemClickListener) { this.listener = listener } interface OnItemClickListener { fun onItemClickListener(v: View, pos: Int) } } 对象中的{{1}},如下所示。

编辑:我已经更改了代码以利用Kotlin的合成视图缓存,您不需要设置一个等于{{1}}之类的视图的变量来获取这些好处

{{1}}

答案 2 :(得分:2)

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

Android Studio在使用自动填充功能添加来自ViewHolder(itemView)的构造函数参数时会自动添加该可空操作符。