Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

android - How to bind view in RecyclerView.ViewHolder with kotlin

What makes me puzzled is how to bind view in Recycleler.ViewHolder. This is my simple adapter and how to Convert it to kotlin use kotlin-android-extensions without 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);
  }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The posted solution works, but I'd like to add something to it. The purpose of the viewholder pattern is to only make the expensive findViewById calls once for every view, and then hold those references inside the ViewHolder, and access the views from there whenever you need to bind one.

However, calling holder.itemView.tv_title.text in the onBindViewHolder method will cause a findViewById call to find the View that has the id tv_title within the itemView every time the viewholder is bound. This basically eliminates the performance gains and caching idea that viewholders are for.

You can make use of the viewholder pattern and Kotlin Android Extensions at the same time by adding a property to your ViewHolder, and initializing it with a call made with Extensions, like so:

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

Then you can access the View through this property:

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

    holder.itemView.setOnClickListener { v ->
        mListener?.onItemClickListener(v, holder.layoutPosition)
    }
}

Lastly, I'd suggest getting rid of the !! operator, and performing a null check instead:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...