0
0
Android Kotlinmobile~7 mins

Sticky headers in Android Kotlin

Choose your learning style9 modes available
Introduction

Sticky headers help keep section titles visible while you scroll through a list. This makes it easier to know which group of items you are looking at.

When showing a long list of contacts grouped by the first letter.
When displaying a list of messages grouped by date.
When presenting a menu with categories that should stay visible while scrolling.
When organizing items in a shopping app by category.
Syntax
Android Kotlin
class MyAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { /* create view holder */ }
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { /* bind data */ }
    override fun getItemCount(): Int { /* return item count */ }

    // Implement sticky header logic using ItemDecoration or libraries
}

Sticky headers are usually implemented with RecyclerView and ItemDecoration.

You can also use third-party libraries to simplify sticky header creation.

Examples
Add an ItemDecoration to RecyclerView to enable sticky headers.
Android Kotlin
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.adapter = MyAdapter()
recyclerView.addItemDecoration(StickyHeaderDecoration())
Custom ItemDecoration can be used to draw sticky headers on top of list items.
Android Kotlin
class StickyHeaderDecoration : RecyclerView.ItemDecoration() {
    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        // Draw header that sticks at top
    }
}
Sample App

This example shows a simple list of fruits grouped by their first letter. The sticky header stays visible at the top as you scroll through the list.

Android Kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = SimpleAdapter(getSampleData())
        recyclerView.addItemDecoration(SimpleStickyHeaderDecoration(recyclerView.adapter as SimpleAdapter))
    }

    private fun getSampleData(): List<Pair<String, String>> {
        return listOf(
            "A" to "Apple",
            "A" to "Avocado",
            "B" to "Banana",
            "B" to "Blueberry",
            "C" to "Cherry",
            "C" to "Coconut"
        )
    }
}

class SimpleAdapter(private val items: List<Pair<String, String>>) : RecyclerView.Adapter<SimpleAdapter.ViewHolder>() {
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView = view.findViewById(android.R.id.text1)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = items[position].second
    }

    override fun getItemCount(): Int = items.size

    fun getHeaderForPosition(position: Int): String = items[position].first
}

class SimpleStickyHeaderDecoration(private val adapter: SimpleAdapter) : RecyclerView.ItemDecoration() {
    private val paint = Paint().apply {
        color = Color.LTGRAY
        textSize = 48f
        isAntiAlias = true
    }

    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        val left = parent.paddingLeft.toFloat()
        val right = (parent.width - parent.paddingRight).toFloat()

        if (parent.childCount == 0) return

        val child = parent.getChildAt(0)
        val position = parent.getChildAdapterPosition(child)
        if (position == RecyclerView.NO_POSITION) return

        val header = adapter.getHeaderForPosition(position)
        val top = parent.paddingTop.toFloat()

        paint.color = Color.LTGRAY
        c.drawRect(left, top, right, top + 60f, paint)
        paint.color = Color.BLACK
        c.drawText(header, left + 20f, top + 45f, paint)
    }
}
OutputSuccess
Important Notes

Sticky headers improve user experience by showing context while scrolling.

Implementing sticky headers requires careful drawing on RecyclerView's canvas.

Test on different screen sizes to ensure headers display correctly.

Summary

Sticky headers keep section titles visible during scrolling.

Use RecyclerView with ItemDecoration to create sticky headers.

Custom drawing is needed to show headers that stick at the top.