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

shi*_*you 26 android kotlin

令我困惑的是如何绑定视图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);
  }

}
Run Code Online (Sandbox Code Playgroud)

zsm*_*b13 47

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

但是,调用holder.itemView.tv_title.textonBindViewHolder方法将导致findViewById调用在每次绑定视图时查找View具有id的id .这基本上消除了观看者所要求的性能提升和缓存理念.tv_titleitemView

您可以通过向您添加属性ViewHolder并使用Extensions进行的初始化来同时使用视图模式和Kotlin Android Extensions,如下所示:

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val title = itemView.tv_title
}
Run Code Online (Sandbox Code Playgroud)

然后您可以View通过此属性访问:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.title.text = mRooms!!.get(position).getLocation()

    holder.itemView.setOnClickListener { v ->
        mListener?.onItemClickListener(v, holder.layoutPosition)
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我建议删除!!运算符,然后执行空检查:

mRooms?.let { rooms ->
    holder.title.text = rooms[position].getLocation()
}
Run Code Online (Sandbox Code Playgroud)


Nat*_*ine 8

只需确保你apply plugin: 'kotlin-android-extensions'的应用程序gradle文件(不是你的root gradle),然后只使用Convert Java文件到Kotlin文件快捷方式.删除Butterknife代码并直接引用itemView.tv_title您的ViewHolder对象,如此.

编辑:我已经改变了代码以利用Kotlin的合成视图缓存,你不需要设置一个等于视图的变量val title = itemView.tv_title来获得这些好处

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

}
Run Code Online (Sandbox Code Playgroud)