android gridlayout row and column not match the result

Viewed 202

I want to create a GridLayout

Here is my setting from server:

 items.add(listOf(4, 3, 0, 0)) -> start at x: 0 - y:0 expand horizontal : 4, vertical 3
 items.add(listOf(1, 1, 0, 3)) -> start at x: 0 - y:3 expand horizontal : 1, vertical 1
 items.add(listOf(1, 1, 1, 3)) -> start at x: 1 - y:3 expand horizontal : 1, vertical 1
 items.add(listOf(1, 1, 2, 3)) -> start at x: 2 - y:3 expand horizontal : 1, vertical 1
 items.add(listOf(1, 1, 3, 3)) -> start at x: 3 - y:3 expand horizontal : 1, vertical 1           

And here is my code to draw the table:

private fun populateTable(){
        val items = AppUtil.getListItemsForGroupLayout(layoutCode)
        val totalRows = AppUtil.getRowOrColumns(layoutCode) -> 4 rows
        val totalCols = AppUtil.getRowOrColumns(layoutCode) -> 4 columns

        tableView.columnCount = totalCols
        tableView.rowCount = totalRows

        items.forEach {
            val params = GridLayout.LayoutParams()
            params.width = 0
            params.height = 0

            params.rowSpec = GridLayout.spec(it[3], it[1].toFloat())
            params.columnSpec = GridLayout.spec(it[2], it[0].toFloat())

            val view = TextView(this@CallScreen)
            view.text = "${it[3]} - ${it[2]} - ${it[1]} - ${it[0]}"
            view.setBackgroundColor(Int.randomColor())
            view.layoutParams = params
            tableView.addView(view)
        }
    }

But the result is not the same:

enter image description here

Can someone tech me the problem? Thanks

2 Answers

I don't think these two lines do what you want:

   params.rowSpec = GridLayout.spec(it[3], it[1].toFloat())
   params.columnSpec = GridLayout.spec(it[2], it[0].toFloat())

According to your comments, it[0] contains colspan and it[1] contains rowspan, but after converting them to float, an overload spec(int start, float weight) is called, which takes weight factor as second argument and size (colspan or rowspan) is 1.

Perhaps overload spec(int start, int size, float weight) will be more appropriate:

   params.rowSpec = GridLayout.spec(it[3], it[1], it[1].toFloat())
   params.columnSpec = GridLayout.spec(it[2], it[0], it[0].toFloat())
   params.rowSpec = GridLayout.spec(it[3], it[1].toFloat())
   params.columnSpec = GridLayout.spec(it[2], it[0].toFloat())

Here you are using this version that provides only the start & weight values.

Looking into other overloaded versions of GridLayout.spec, there is another parameter (size) that also controls this behavior as by looking into the GridLayout source code, all these overloaded methods call the private constructor:

    private Spec(boolean startDefined, int start, int size, Alignment alignment, float weight) {
        this(startDefined, new Interval(start, start + size), alignment, weight);
    }

Solution:

To fix this we need to use the size parameter by using this overloaded version in setting the params.columnSpec:

So, in your code replace:

params.columnSpec = GridLayout.spec(it[2], it[0].toFloat())

With:

params.columnSpec = GridLayout.spec(it[2], it[0], 1f)

Preview:

enter image description here

Related