In this lab, you will learn how to manipulate lists in android.

Prerequisites

A ListView is a android View that stores a scrollable collection of views.

Some common examples of ListViews in apps include:

Consider an instagram feed. What would happen if the app loaded 1000 items into the feed?

Recycler View is a powerful and flexible Android View used for displaying large sets of data efficiently by recycling views that are no longer visible.

It's a more modern, flexible, and performant approach to displaying lists as compared to a regular ListView.

From the android documentation:

RecyclerView makes it easy to efficiently display large sets of data. You supply the data and define how each item looks, and the RecyclerView library dynamically creates the elements when they're needed.

As the name implies, RecyclerView recycles those individual elements. When an item scrolls off the screen, RecyclerView doesn't destroy its view. Instead, RecyclerView reuses the view for new items that have scrolled onscreen. RecyclerView improves performance and your app's responsiveness, and it reduces power consumption.

Features:

Key Components:

In general, there are a few components that are necessary for implementing a listview

This project would give you practical experience in creating an app with a list. It will use the recycleradapter

The data source

  1. Create a new Kotlin class Movie to store a title and description of a movie.
    • Right click the folder with the file MainActivity.kt
    • Hover over new
    • Click Kotlin Class/File
  2. Modify the movie class to have two parameters
    • The title
    • The description
class Movie(val title:String, val description:String)

The List Container

  1. Modify activity_main.xml and remove the "Helo World" TextView.
  2. Insert a RecyclerView as a child element inside the parent element
  3. Give the recycler an ID @+id/rvMovies. This will be used as a lookup value in the code to access this element .
  4. Ensure that the following properties are set
    • Layout width should be match_parent
    • Layout height should be match_parent
   <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvMovies"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

Define the layout for a Single Item

  1. Create a new xml file item_movie.xml that would describe what a single item looks like
    • Right click the layout folder
    • Hover over new
    • Click "Layout Resource File"
    • Name it appropriately
  2. Change the layout height of the root element to wrap_content
  3. Create two children TextViews
    1. The first textview should have an id @+id/titleTextView
    2. The second textview should have an id @+id/descriptionTextView
  4. Apply any constraint layouts to achieve the layout you desire.
<!-- Constraint layout properties for the two TextViews 
below are left out for brevity -->

<TextView
    android:id="@+id/titleTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView"

        />

<TextView
    android:id="@+id/descriptionTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView"
    
    />

The Adapter

  1. Create a new kotlin class named MovieAdapter.kt
    • Right click the folder that has MainActivity.kt
    • Hover over new
    • Select Kotlin class/file
  2. Let this class extend the RecyclerView.Adapter abstract class with a type MovieAdapter.ViewHolder
class MovieAdapter(private val movies: List<Movie>) : RecyclerView.Adapter<MovieAdapter.ViewHolder>() {
    // Code redacted
}
  1. Create the inner class (the ViewHolder class). This class should be inside the MovieAdapter class.

From the android documentation

Each individual element in the list is defined by a view holder object. When the view holder is created, it doesn't have any data associated with it. After the view holder is created, the RecyclerView binds it to its data. You define the view holder by extending RecyclerView.ViewHolder.

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val titleTextView: TextView = itemView.findViewById(R.id.titleTextView)
        val descriptionTextView: TextView = itemView.findViewById(R.id.descriptionTextView)
    }
  1. Override and implement the required methods
    1. onCreateViewHolder (creates the view container i.e. the ‘template')
    2. onBindViewHolder (populates the template with the correct information for that item in the list)
    3. getItemCount (holds the amount of items in the list)
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_movie, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val movie = movies[position]

        holder.titleTextView.text = movie.title
        holder.descriptionTextView.text = movie.description
    }

    override fun getItemCount(): Int {
        return movies.size
    }

Putting it all together

At this point we have the following items:

  1. A data class that defines the structure of the items in the list Movies.kt
  2. The layout template on how a single item in the list looks item_movie.xml
  3. A View in the main layout that would render the list. i.e. The RecyclerView inside activity_main.xml
  4. An adapter class that has the logic on selecting the template and populating the data MovieAdapter.kt

The only thing left to do is put it all together.

The final touches

The following instructions should be performed in the file MainActivity.kt

  1. Create a new function in MainActivity.kt called getMovieData()
   private fun getMovieData():List<Movie>{
        return listOf(
            Movie("Lorem Ipsum", "This is a long description of a movie called lorem ipsum and this is awesome."),
            Movie("Movie Two", "This is a long description of a movie called Movie Two and this is awesome."),
            Movie("Fast and Furious", "This is a long description of a movie called Fast and Furious and this is awesome."),
            Movie("Android reigns Supreme", "No description needed. Android is just better"),
            Movie("iPhone", "It took me so many years to be able to pause video while recording. Call me the internet explorer of the mobile world"),
            Movie("Water Bottle", "Thirsty people drink water. Stay hydrated."),
            Movie("The struggle", "When is A1 going to drop? Stay tuned for the next episode"),
            Movie("The week 7", "It's the unspoken rule that the 7th week is just... Tears."),
            Movie("The week 8", "I survived week 7. I think. Coursework marks may say otherwise"),
            Movie("The week 11", "Coursework really did say otherwise. Watch the grind of the students going full tryhard for finals"),
            Movie("Week 12", "The grind continues..."),
            Movie("Week 13", "Teaching is done, will any students fall into the trap of getting relaxed before exams?"),
            Movie("Christmas", "What does Christmas have in store? Would I get my marks? Did I pass? Stay tuned"),
        )
    }
  1. Create another function in MainActivity.kt called renderList. Ensure that this function is called last in the onCreate
    private fun renderList(){
        val mainLayout: RecyclerView = findViewById(R.id.rvMovies)
        val movies:List<Movie> = getMovieData()
        val movieAdapterInst = MovieAdapter(movies)
        mainLayout.adapter = movieAdapterInst
        mainLayout.layoutManager = LinearLayoutManager(this)
    }

The LayoutManager is used to define the general layout specs of the list. By default, the items will be vertically scrollable, but, the properties of the LinearLayoutManager can be used to change this to a horizontal scrolling list

With the successful completion of the lab, you should have an appreciation on how list data is rendered in an android app. With this lab, you are well equipped to replicate lists you're familiar with , it's now just a matter of

  1. Figuring out what structure best suits the data.
  2. Figuring out how to define the layout of the item template

Example 1: Instagram DMs

An insta DM class could be defined with the properties

How would you create a function getChatData that's similar to the getMovieData function to return a list of recent chats?

How would you create a file similar to the item_movie.xml to define the layout of a single chat item?

Example 2: Whatsapp recent chats

The whatsapp recent chats list could be defined as a Chat class with the properties

These items are completely optional.

The completed source code

Recycler View

The App