Slide 1

Slide 1 text

RecyclerView Developer’s Deep Dive Divya Jain Twitter: @divyajain2405 Github : djain2405

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Legacy ListView private val bookListView = findViewById(R.id.book_list_view) val bookItems : List = datasource.getBooks() val adapter = ArrayAdapter(this,android.R.layout.simple_list_item_1, bookItems) bookListView.adapter = adapter

Slide 4

Slide 4 text

Adapter “Bridge between data source and the UI component displaying the data“ ListView Adapter Data Source

Slide 5

Slide 5 text

Custom Adapter class BookAdapter: BaseAdapter() { override fun getCount(): Int = dataSource.size override fun getItem(position: Int): Any = dataSource[position] override fun getItemId(position: Int): Long = position.toLong() override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val rowView = inflater.inflate(R.layout.list_book_item, parent, false) val titleTextView = rowView.findViewById(R.id.book_title) as TextView val authorTextView = rowView.findViewById(R.id.book_author) as TextView // populate book data to itemview val book = getItem(position) as Book titleTextView.text = book.title authorTextView.text = book.author return rowView } }

Slide 6

Slide 6 text

ViewHolder Pattern private class ViewHolder { lateinit var titleTextView: TextView lateinit var authorTextView: TextView } override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val rowView = inflater.inflate(R.layout.list_book_item, parent, false) val holder: ViewHolder = ViewHolder() holder.titleTextView = view.findViewById(R.id.book_title) as TextView holder.authorTextView = view.findViewById(R.id.book_author) as TextView // populate book data to itemview val book = getItem(position) as Book holder.titleTextView.text = book.title holder.authorTextView.text = book.author return rowView }

Slide 7

Slide 7 text

RecyclerView “RecyclerView is a UI element to efficiently display large sets of data.” Viewport Scrap View scrolling Recycle Views Dirty View

Slide 8

Slide 8 text

RecyclerView ● ViewGroup containing views for the data ● Mandatory ViewHolder defining each of the element - recyclerview binds the viewholder to the data ● Adapter defines methods where view is requested and binds to data ● LayoutManager arranges the items in the list

Slide 9

Slide 9 text

class MyRecyclerAdapter(private val dataSet: Array) : RecyclerView.Adapter() { class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textView: TextView init { textView = view.findViewById(R.id.textView) } } override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.text_row_item, viewGroup, false) return ViewHolder(view) } override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { viewHolder.textView.text = dataSet[position] } override fun getItemCount() = dataSet.size }

Slide 10

Slide 10 text

private val bookRecyclerView = findViewById(R.id.book_list_view) val bookItems : Array = datasource.getBookTitles() val adapter = MyRecyclerViewAdapter(bookItems) bookRecyclerView.adapter = adapter

Slide 11

Slide 11 text

Recyclerview over ListView ● Compulsory ViewHolder Pattern ● Required Layout Manager ● Item Animator ● Item Decorator ● Customizations for interaction with list item ● Optimized performance

Slide 12

Slide 12 text

Tips for further optimizations ● setHasFixedSize(true) ● setItemViewCacheSize(size) ● adapter.setHasStableIds(true)

Slide 13

Slide 13 text

Recyclerview with Multiple type views companion object { const val BOOK_TYPE = 0 const val GENRE_TYPE = 1 } sealed class DataItem(val type: Int) { class BookItem(val book: Book): DataItem(BOOK_TYPE) class GenreItem(val genreName: String): DataItem(GENRE_TYPE) } override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): RecyclerView.ViewHolder { return when (viewType) { BOOK_TYPE -> BookViewHolder(parent) GENRE_TYPE -> GenreViewHolder(parent) } } Book 1 Book 2 Genre 1 Genre 2 Book 1

Slide 14

Slide 14 text

Recyclerview with Multiple type views override fun getItemViewType(position: Int): Int = dataSet[position].type override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val viewType = getItemViewType(position) val item = dataSet[position] when (viewType) { BOOK_TYPE -> { (holder as BookViewHolder).bind(item) } GENRE_TYPE -> { (holder as GenreViewHolder).bind(item) } } } Book 1 Book 2 Genre 1 Genre 2 Book 1

Slide 15

Slide 15 text

ConcatAdapter Sequentially combine multiple adapters into a single RecyclerView val adapterOne: AdapterOne = {} val adapterTwo: AdapterTwo = {} val adapterThree: AdapterThree = {} val concatAdapter = ConcatAdapter(adapterOne, adapterTwo, adapterThree) recyclerView.adapter = concatAdapter ConcatAdapters

Slide 16

Slide 16 text

Nested RecyclerView SearchBar Parent RecyclerView Activity/Fragment Category Name Child Recyclerview Parent recyclerview item Child recyclerview item CardView TextView

Slide 17

Slide 17 text

Recyclerview in Compose @Composable fun DogListingScreen(viewModel: DogListingViewModel) { val dogs = viewModel.dogsList.observeAsState(initial = emptyList()) LazyColumn( contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp) ) { items( items = dogs, itemContent = { DogListItem(dog = it) }) } } djain2405/jetpack-compose-adopt-happily

Slide 18

Slide 18 text

Summary ● A flexible view for providing a limited window into a large data set. ● Faster , optimized performance ● Versatile API ● Recycled Views , dynamic list of data ● Reduction in memory/power consumption ● Enhanced responsiveness

Slide 19

Slide 19 text

Thank You! Divya Jain Twitter: @divyajain2405 Github : djain2405