Search code examples
androidandroid-recyclerviewgridlayoutmanageritem-decoration

Delete Extra Item Decoration within last row empty columns In a Recycler View


Im trying to delete the empty column Item decoration as per the below Image. I Initially thought to restrict the spancount for the last row as per the content using below code in comments but however Im not successful.

below is the code and Image as a result.

enter image description here

 val taskDatesView: RecyclerView = binding.taskDatesRecyclerView
    val manager = GridLayoutManager(context,10)
    taskDatesView.layoutManager = manager
    taskDatesView.adapter = taskDatesAdapter

    createTasksViewModel.taskDates.observe(viewLifecycleOwner) {
        it?.let(taskDatesAdapter::setTaskDates)
        val decoration = DividerItemDecoration(context, HORIZONTAL)
        taskDatesView.addItemDecoration(decoration)
        /*manager.spanSizeLookup = object :SpanSizeLookup(){
            override fun getSpanSize(position: Int): Int {
                val lastRowCount = (taskDatesAdapter.itemCount%10)
                if(position>taskDatesAdapter.itemCount -lastRowCount){
                    return lastRowCount
                }
                return 10
            }
        }*/
        

when I uncommented the code and run the app below is the result

enter image description here

Any code references or links will be helpful. Thanks in Advance.


Solution

  • Within Custom Divider, modifying the bottom padding based on the lastRowCount it is working as expected.

    Below is the working code and result also added comments within code for better understanding

    fun drawHorizontal(c: Canvas?, parent: RecyclerView) {
        val noOfColumns = 10
        val top = parent.paddingTop
        var bottom = parent.height - parent.paddingBottom
        val childCount = parent.childCount
        // values required not to draw the bottom for last empty columns
        val lastRowCount = childCount % noOfColumns
        val numOfRows = childCount / noOfColumns
        for (i in 0 until childCount) {
            val child = parent.getChildAt(i)
            val params = child.layoutParams as RecyclerView.LayoutParams
            // this can be optimized to calculate only once for every row
            val rowNumber = ((i + 1) / noOfColumns) + 1
            // Within every row after crossing the lastRowCount the bottom should not be extended
            if ((i * rowNumber) - (lastRowCount - 1) > 0) {
                bottom = (child.height * (numOfRows))
            }
            val left = child.right + params.rightMargin + mDivider.intrinsicHeight
            val right = left + mDivider.intrinsicWidth
            mDivider.setBounds(left, top, right, bottom)
            mDivider.draw(c!!)
        }
    }
    

    enter image description here

    If we need both vertical and horizontal orientations, use above and the below code

    fun drawVertical(c: Canvas?, parent: RecyclerView){
        val dividerLeft = parent.paddingLeft
        val dividerRight = parent.width - parent.paddingRight
        val childCount = parent.childCount
        for (i in 0..childCount - 2) {
            val child: View = parent.getChildAt(i)
            val params = child.layoutParams as RecyclerView.LayoutParams
            val dividerTop: Int = child.getBottom() + params.bottomMargin
            val dividerBottom = dividerTop + mDivider.intrinsicHeight
            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
            mDivider.draw(c)
        }
    }
    

    enter image description here