Android RecyclerView with Endless Scrolling in Kotlin

Enhancing User Experience with Endless Scrolling in Android RecyclerView using Kotlin

Android RecyclerView with Endless Scrolling in Kotlin
Photo by Kerde Severin

As an Android developer, you may have encountered scenarios where you need to display a large list of data that can keep expanding while the user scrolls. In such situations, using the RecyclerView with endless scrolling can provide a seamless user experience by dynamically loading more items as the user reaches the end of the list.

Before we start, check our previous articles on RecyclerView

In this blog post, we will explore how to implement endless scrolling in Android RecyclerView using Kotlin. We will create a simple app that fetches data from an API and loads it into the RecyclerView while allowing the user to scroll infinitely.

Setting up the Project

To get started, create a new Android project in Android Studio and add the necessary dependencies to your build.gradle file.

dependencies {
    // RecyclerView
    implementation 'androidx.recyclerview:recyclerview:1.3.0'

    // Network library
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

    // Asynchronous HTTP client
    implementation 'com.squareup.okhttp3:okhttp:4.9.1'
}

Implementing the RecyclerView

First, let's set up the RecyclerView in our layout file (activity_main.xml). Replace the default ConstraintLayout with a RecyclerView and provide an id.

 <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Next, we need to create a layout file (item_layout.xml) to represent a single item in the RecyclerView. Customize this layout file based on your data requirements.

  <!-- item_layout.xml -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <!-- Customize the layout as per your data -->
    <TextView
        android:id="@+id/titleTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
        
    <TextView
        android:id="@+id/descriptionTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
        
</LinearLayout>

Now let's create the ViewHolder class to hold the views of each item in the RecyclerView.

class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val titleTextView: TextView = itemView.findViewById(R.id.titleTextView)
    val descriptionTextView: TextView = itemView.findViewById(R.id.descriptionTextView)
}


Fetching Data with Retrofit

To fetch data from an API, we can use the Retrofit library. Create an interface (ApiService.kt) to define the API endpoints.

interface ApiService {
    @GET("items")
    suspend fun getItems(@Query("page") page: Int, @Query("limit") limit: Int): List<Item>
}

Next, create a singleton object for Retrofit (RetrofitClient.kt) and provide the necessary base URL.

object RetrofitClient {
    private const val BASE_URL = "https://api.example.com/"

    private val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(OkHttpClient())
            .build()
    }

    val apiService: ApiService by lazy {
        retrofit.create(ApiService::class.java)
    }
}

Endless Scrolling Implementation

Now, let's implement the endless scrolling functionality in our RecyclerView. Create a new Kotlin file (EndlessScrollListener.kt) and define a custom scroll listener class.

abstract class EndlessScrollListener : RecyclerView.OnScrollListener() {
    private var previousTotalItems = 0
    private var loading = true
    private var currentPage = 0

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        val layoutManager = recyclerView.layoutManager as LinearLayoutManager
        val visibleItemCount = layoutManager.childCount
        val totalItemCount = layoutManager.itemCount
        val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()

        if (loading && totalItemCount > previousTotalItems) {
            loading = false
            previousTotalItems = totalItemCount
        }
        
        val visibleThreshold = 5
        if (!loading && (totalItemCount - visibleItemCount <= firstVisibleItemPosition + visibleThreshold)) {
            currentPage++
            onLoadMore(currentPage)
            loading = true
        }   
    }

    abstract fun onLoadMore(page: Int)
}

Updating the MainActivity

Finally, let's update the MainActivity.kt file to use the RecyclerView and implement the endless scrolling.

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var itemAdapter: ItemAdapter
    private lateinit var layoutManager: LinearLayoutManager

    private var currentPage = 0
    private val PAGE_LIMIT = 20

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recyclerView)
        layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager

        itemAdapter = ItemAdapter()
        recyclerView.adapter = itemAdapter

        recyclerView.addOnScrollListener(object : EndlessScrollListener() {
            override fun onLoadMore(page: Int) {
                fetchItems(page, PAGE_LIMIT)
            }
        })

        fetchItems(currentPage, PAGE_LIMIT)
    }

    private fun fetchItems(page: Int, limit: Int) {
        // Make API request using Retrofit
        val apiService = RetrofitClient.apiService
        CoroutineScope(Dispatchers.Main).launch {
            val response = apiService.getItems(page, limit)
            if (response.isNotEmpty()) {
                itemAdapter.addData(response)
            }
        }
    }
}

Conclusion

You can customize this implementation further based on your specific requirements, such as adding loading indicators or swipe gestures.

In this blog post, we learned how to implement endless scrolling in Android RecyclerView using Kotlin. By dynamically loading more items as the user reaches the end of the list, we can provide a smooth scrolling experience. We set up the RecyclerView, fetched data using Retrofit, created a custom scroll listener to detect scroll events, and updated the MainActivity to handle the scrolling behavior.

Thanks for reading this article. Hope you would have liked it!. Please share and subscribe to my blog to support.

Pragnesh Ghoda

A forward-thinking developer offering more than 8 years of experience building, integrating, and supporting android applications for mobile and tablet devices on the Android platform. Talks about #kotlin and #android

Post a Comment

Please let us know about any concerns or query.

Previous Post Next Post

Contact Form