Search code examples
androidkotlinandroid-recyclerviewitem-decoration

How to set ItemDecoration only for certain ViewType?


I want to draw a default ItemDecoration only for Header Type into RecycleView. But divider is shown for each ViewType.

Custom decoration:

class DividerDecoration(context: Context, orientation: Int)
    : DividerItemDecoration(context, orientation){

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val position = parent.getChildAdapterPosition(view)
        val viewType = parent.adapter!!.getItemViewType(position)
        if (viewType == ITEM_VIEW_TYPE_HEADER){
            super.getItemOffsets(outRect, view, parent, state)
        } else {
            outRect.setEmpty()
        }
    }
}

Set:

val itemDecoration = DividerDecoration(binding.recyclerView.context, 
                                       DividerItemDecoration.VERTICAL)
binding.recyclerView.addItemDecoration(itemDecoration)

Any suggestions to why does this happen?

UPDATE

The code above is work. But with a bug. After starting the application, the divider appears in all elements, and then only the right ones. Why is this happening?

enter image description here


Solution

  • Problem

    My mistake consists of the conviction to use ItemDecoration in order to set custom dividers for different ViewType. I have developed a clear belief that such a custom dividers should do only ItemDecoration.

    According image gif from my question, it's gives a bug. I couldn't find a solution. The other posts on StackOverflow is offering to override the methods: getItemOffsets() and onDraw(). I tried to implement at least four case. And they all ended up with a drawing bug (similar to gif from my question).

    Search

    I don't know what causes these drawing errors. Thanks to Tenfour04's answer and comments. I changed my keywords for searching and found simple solution.

    By the way, the design of my application adopts some features of the design of applications from Google. I decompiled the apk of one of those apps. And found the resources that make the separator exactly as described in the solution. In this regard, I can consider this decision the best practices from Google.

    Solution

    I have two ViewType. Each with its own layout. The solution is to add a separator to the header layout.

    Because the ViewTypeHeader only appears if there are nested elements, in my case I don't need to add conditions with Visible for the last or first element.

    layout\ViewTypeHeader.xml

    <LinearLayout ...>
    
        <TextView ... />
    
        <!-- This -->
        <View style="@style/DividerStyle" />
    
    </LinearLayout>
    

    values/styles.xml

    <style name="DividerStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">@dimen/dividerHeight</item>
        <item name="android:background">@android:color/black</item>
    </style>
    

    Conclusion

    If there are several ViewType - forget about ItemDecoration. Save a lot of time.

    enter image description here