This example demonstrates how to implement an endless list with RecyclerView in Android using Kotlin.
Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.
Step 2 − Add the following code to res/layout/activity_main.xml.
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardElevation="2dp" app:cardUseCompatPadding="true"> <TextView android:id="@+id/textViewItem" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textColor="@android:color/holo_blue_bright" android:textStyle="bold" /> </androidx.cardview.widget.CardView>
Step 3 − Add the following code to src/MainActivity.kt
import android.os.Bundle import android.os.Handler import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView class MainActivity : AppCompatActivity() { lateinit var recyclerView: RecyclerView lateinit var recyclerViewAdapter: RecyclerViewAdapter var rowsArrayList: ArrayList<String> = ArrayList() var isLoading = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) title = "KotlinApp" recyclerView = findViewById(R.id.recyclerView) populateData() initAdapter() initScrollListener() } private fun initScrollListener() { recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) val linearLayoutManager = recyclerView.layoutManager as LinearLayoutManager? if (!isLoading) { if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == rowsArrayList.size − 1) { //bottom of list! loadMore() isLoading = true } } } }) } private fun initAdapter() { recyclerViewAdapter = RecyclerViewAdapter(rowsArrayList) recyclerView.layoutManager = LinearLayoutManager(applicationContext) recyclerView.adapter = recyclerViewAdapter } private fun populateData() { for (i in 0..9) { rowsArrayList.add("Number $i") } } private fun loadMore() { rowsArrayList.add(null.toString()) recyclerViewAdapter.notifyItemInserted(rowsArrayList.size − 1) val handler = Handler() handler.postDelayed(Runnable { rowsArrayList.removeAt(rowsArrayList.size − 1) val scrollPosition = rowsArrayList.size recyclerViewAdapter.notifyItemRemoved(scrollPosition) var currentSize = scrollPosition val nextLimit = currentSize + 10 while (currentSize − 1 < nextLimit) { rowsArrayList.add("Number $currentSize") currentSize++ } recyclerViewAdapter.notifyDataSetChanged() isLoading = false }, 2000) } }
Step 4 − Create a new class RecyclerViewAdapter.kt and add the following code −
import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ProgressBar import android.widget.TextView import androidx.annotation.NonNull import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.ViewHolder class RecyclerViewAdapter internal constructor(private val itemList: List<String>) : RecyclerView.Adapter<ViewHolder>() { private val viewItemType = 0 @NonNull override fun onCreateViewHolder( @NonNull parent: ViewGroup, viewType: Int ): ViewHolder { return if (viewType == viewItemType) { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_row, parent, false) ItemViewHolder(view) } else { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_loading, parent, false) LoadingViewHolder(view) } } override fun onBindViewHolder(@NonNull viewHolder: ViewHolder, position: Int) { if (viewHolder is ItemViewHolder) { populateItemRows(viewHolder, position) } else if (viewHolder is LoadingViewHolder) { showLoadingView(viewHolder, position) } } override fun getItemViewType(position: Int): Int { return viewItemType } private inner class ItemViewHolder internal constructor(@NonNull itemView: View) : ViewHolder(itemView) { internal var tvItem: TextView = itemView.findViewById(R.id.textViewItem) } private class LoadingViewHolder internal constructor(itemView: View) : ViewHolder(itemView) { var progressBar: ProgressBar = itemView.findViewById(R.id.progressBar) } override fun getItemCount(): Int { return itemList.size } private fun showLoadingView(viewHolder: LoadingViewHolder, position: Int) {} private fun populateItemRows(viewHolder: ItemViewHolder, position: Int) { val item = itemList[position] viewHolder.tvItem.text = item } }
Step 5 − Create a Layout resource file item_row.xml and add the following −
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardElevation="2dp" app:cardUseCompatPadding="true"> <TextView android:id="@+id/textViewItem" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textColor="@android:color/holo_blue_bright" android:textStyle="bold" /> </androidx.cardview.widget.CardView>
Step 6 − Create a Layout resource file item_loading.xml and add the following −
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ProgressBar android:id="@+id/progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:indeterminate="true" android:paddingLeft="8dp" android:paddingRight="8dp" /> </LinearLayout>
Step 7 − Add the following code to androidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android" package="com.example.q11"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Let's try to run your application. I assume you have connected your actual Android Mobile device with your computer. To run the app from android studio, open one of your project's activity files and click the Run icon from the toolbar. Select your mobile device as an option and then check your mobile device which will display your default screen