There is a difficulty in writing two methods: onBindViewHolder , onCreateViewHolder . Not quite catching up on what's needed (trying to redo the listview in recyclerview)

Also in ListView was the getView method, where the following logic was implemented

  override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { var convertView = convertView if (convertView == null) { convertView = layoutInflater.inflate(R.layout.list_item_language_picker, parent, false) } val item = getItem(position) as String val locale = LocaleTools().parseStringLocale(item) var text = LocaleTools().getDisplayLanguage(locale) if (!locale.getDisplayCountry(locale).isEmpty()) { text += (" (" + locale.getDisplayCountry(locale) + ")") } (convertView!!.findViewById(R.id.itemInfo) as CustomTextView).text = text convertView.findViewById(R.id.check).visibility = if (item == selection) View.VISIBLE else View.GONE return convertView } 

To be honest, I don’t quite understand where it can be crammed into the recyclerView adapter.

  • one
    These are adapter methods, not ViewHolder 's. Here in this book is described in detail why they are needed. - post_zeew

1 answer 1

In onCreateViewHolder you must inflate the item markup and create an AdapterHolder from it. Notice how and where the view initialized.

onBindViewHolder comes your AdapterHolder , created in onCreateViewHolder . In it you need to fill with data each item in the list.

Here is my first adapter when I started trying RecyclerView . I think everything will become clear. If not, write comments. Here I am downloading data from the database. Something of type SimpleCursorAdapter .

 public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.AdapterHolder> { Cursor cursor; public class AdapterHolder extends RecyclerView.ViewHolder { TextView time, date, text; CardView card; AdapterHolder(View itemView) { super(itemView); time = (TextView)itemView.findViewById(R.id.note_item_time); date = (TextView)itemView.findViewById(R.id.note_item_date); text = (TextView)itemView.findViewById(R.id.note_text); card = (CardView)itemView; } } NotesAdapter(Cursor cursor) { this.cursor = cursor; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); } @Override public AdapterHolder onCreateViewHolder(ViewGroup viewGroup, int p2) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.note_item, viewGroup, false); AdapterHolder pvh = new AdapterHolder(v); return pvh; } @Override public void onBindViewHolder(final AdapterHolder holder, final int position) { cursor.moveToPosition(position); final Long id = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); String date = cursor.getString(cursor.getColumnIndex(Database.NOTES_DATE)); String time = cursor.getString(cursor.getColumnIndex(Database.NOTES_TIME)); final String color = cursor.getString(cursor.getColumnIndex(Database.NOTES_COLOR)); final String text = cursor.getString(cursor.getColumnIndex(Database.NOTES_TEXT)); holder.time.setText(time); holder.date.setText(date); holder.text.setText(text); holder.card.setCardBackgroundColor(Color.parseColor(color)); } @Override public int getItemCount() { return cursor.getCount(); } } 

For convenience, make the bind(int position) method in the holder and call it in onBindViewHolder

 holder.bind(position); 

And inside the bind method they write the logic of data binding. It is, indeed, effective.

 People people = peoples.get(position); textview_name.setText(people.name); //etc.. 

To set up an onItemClickListener listener like in ListView :

1) The root markup element (which contains everything else we write

 android:clickable="true" android:focusable="true" <!-- Π½Π΅ знаю Π·Π°Ρ‡Π΅ΠΌ --> android:background="?attr/selectableItemBackground" <!-- ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ --> 

2) In the constructor of the holder set

 itemView.setOnClickListener(this); 

3) The holder itself inherits from the interface

 public class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener 

4) Implement the onClick(View v) method inside the holder

5) Create a listener variable in the adapter.

 private OnItemClickListener listener; 

6) Create an interface in the adapter

 public interface OnItemClickListener { void onItemClick(View v); //ΠΌΠΎΠΆΠ½ΠΎ сразу ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ модСль //void onItemClick(People p); //ΠΈΠ»ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ //void onItemClick(int position); } 

7) Create a method in the adapter

 public void setOnItemClickListener (OnItemClickListener listener) { this.listener = listener; } 

8) In the onClick method (see step 4) we write

 @Override public void onClick(View v) { switch(v.getId()) { case R.id.root_item_view: listener.onItemClick(v); //ΠΈΠ»ΠΈ модСль //listener.onItemClick(peoples.get(getAdapterPosition())); //ΠΈΠ»ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ //listener.onItemClick(getAdapterPosition()); break; case ... case ... } } 

Now, in the activity / fragment, you can write

 RecyclerView rv = (RecyclerView) findViewById(...); rv.setLayoutManager(new Linear/*Grid/Staggered*/LayoutManager()); RecyclerAdapter adapter = new RecyclerAdapter(datalist); adapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(View v) { //ваша логика } }); rv.setAdapter(adapter); 
  • Thanks in general, the example is clear, but updated the question in order to fully understand - Inkognito
  • @Flippy That is my assumption that the ViewBinder'a logic from SimpleCursorAdapter is transferred to onBindViewHolder was correct? - Leo240
  • Yes. In the constructor of the holder comes a View item, in it you need to search by id for all View . In RecyclerView ViewBinder pattern ViewBinder already out of the box - Flippy
  • Added some info - Flippy
  • @Flippy Thanks, everything works fine. Only another moment I would like to clarify if you need to use CursorLoader with RecyclerView or is it already implemented behind the scenes (for asynchronous data retrieval from the database)? - Leo240