Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将RecyclerView.ViewHolder中的视图与kotlin绑定_Android_Kotlin - Fatal编程技术网

Android 如何将RecyclerView.ViewHolder中的视图与kotlin绑定

Android 如何将RecyclerView.ViewHolder中的视图与kotlin绑定,android,kotlin,Android,Kotlin,让我困惑的是如何在Recycleler.ViewHolder中绑定视图。 这是我的简单适配器,如何将其转换为kotlin使用kotlin android extensions而不使用ButterKnife public class RoomAdapter extends RecyclerView.Adapter<ViewHolder> { private OnItemClickListener mListener; private List<LocationBean&

让我困惑的是如何在
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);
  }

}
公共类RoomAdapter扩展了RecyclerView.Adapter{
私人监听者;
私人名单;
静态类ViewHolder扩展了RecyclerView.ViewHolder{
@BindView(R.id.tv_标题)
文本视图标题;
公共视图持有者(视图项视图){
超级(项目视图);
ButterKnife.bind(这个,itemView);
}
}
公共空间设置数据(列出房间){
M房间=房间;
notifyDataSetChanged();
}
@凌驾
public ViewHolder onCreateViewHolder(视图组父级,int-viewType){
View=LayoutInflater.from(parent.getContext())
.充气(R.layout.item\u first\u select,parent,false);
返回新的ViewHolder(视图);
}
@凌驾
公共无效onBindViewHolder(最终ViewHolder,内部位置){
holder.tvTitle.setText(mRooms.get(position.getLocation());
holder.itemView.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
mListener.onItemClickListener(v,holder.getLayoutPosition());
}
});
}
@凌驾
public int getItemCount(){
返回mRooms==null?0:mRooms.size();
}
公共void setOnItemClickListener(OnItemClickListener侦听器){
mListener=监听器;
}
公共接口侦听器{
void-mclick侦听器(视图v,int-pos);
}
}

只需确保您的应用程序gradle文件(而不是根gradle)中有
应用插件:“kotlin android extensions”
,然后只需使用“将Java文件转换为kotlin文件”快捷方式即可。删除Butterknife代码并直接在
ViewHolder
对象中引用
itemView.tv\u title
,如下所示

编辑:我更改了代码以利用Kotlin的合成视图缓存,您不需要将变量设置为与视图相同的值,如
val title=itemView.tv\u 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)
    }

}
import kotlinx.android.synthetic.main.item\u first\u select.view*
类RoomAdapter:RecyclerView.Adapter(){
私有变量侦听器:MClickListener?=null
私人var房间:列表?=null
类ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
娱乐绑定(房间:房间){
itemView.tv_title.text=room.getLocation()
}
}
乐趣设置数据(房间:列表){
这个房间
notifyDataSetChanged()
}
override onCreateViewHolder(父级:ViewGroup,viewType:Int):ViewHolder{
val view=LayoutInflater.from(parent.context)
.充气(R.layout.item\u first\u select,parent,false)
返回视图保持器(视图)
}
覆盖BindViewHolder(holder:ViewHolder,位置:Int){
房间?得到(位置)?让{room->
固定器(房间)
}
holder.itemView.setOnClickListener{v->
侦听器?.onItemClickListener(v,保持器布局位置)
}
}
重写getItemCount():Int{
返回房间?尺寸?:0
}
有趣的setOnItemClickListener(监听器:OnItemClickListener){
this.listener=listener
}
接口侦听器{
趣味McClickListener(v:视图,位置:Int)
}
}
效果不错,但我想添加一些内容。viewholder模式的目的是只为每个视图调用一次昂贵的
findViewById
,然后将这些引用保存在
viewholder
中,并在需要绑定视图时从那里访问视图

但是,每次绑定viewholder时,在
onBindViewHolder
方法中调用
holder.itemView.tv\u title.text
将导致
findViewById
调用在
itemView
中查找id为
tv\u title
视图。这基本上消除了ViewHolder的性能提升和缓存思想

您可以同时使用viewholder模式和Kotlin Android扩展,方法是将属性添加到
viewholder
,并使用扩展进行调用来初始化它,如下所示:

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val title = itemView.tv_title
}
然后,您可以通过此属性访问
视图

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

其他人回答得很好,我只是想在
类ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView)
中添加一点,在
itemView
之后不应该有可为空的操作符(“
”),kotlin绑定才能工作


Android Studio在使用autocomplete从
ViewHolder(itemView)

添加构造函数参数时,会自动添加可为空的运算符。您应该真正尝试执行端口,并显示在执行此操作时遇到的具体问题。否则,您要求为使用kotlin synthetics的用户提供“please port my code for me”服务,这是一篇很好的文章,展示了如何避免在onBindViewHolder中调用findViewById:正确,因为KAE并不总是调用优化方法“findCachedViewById”,例如这个ViewHolder案例。