Home » Android » android – Set rowSpan or colSpan of a child of a GridLayout programmatically?

android – Set rowSpan or colSpan of a child of a GridLayout programmatically?

Posted by: admin April 23, 2020 Leave a comment

Questions:

I have a GridLayout with 5 columns and 3 rows. Now I can insert arbitrary child views, which is great. Even better is, that I can assign columnSpan=2 to some item in order to span it to 2 columns (the same with rowSpan).

The problem now is, that I cannot assign rowSpan or columnSpan programmatically (i.e. at runtime). Some search suggested something like this:

layoutParams.columnSpec = GridLayout.spec(0, columnSpan);

But I don’t quite understand what the parameters of spec mean (start and size). The documentation is also quite poor at this point.

Any help is highly appreciated!

How to&Answers:
    GridLayout gridLayout = (GridLayout)findViewById(R.id.tableGrid);

    gridLayout.removeAllViews();

    int total = 12;
    int column = 5;
    int row = total / column;
    gridLayout.setColumnCount(column);
    gridLayout.setRowCount(row + 1);
    for(int i =0, c = 0, r = 0; i < total; i++, c++)
    {
        if(c == column)
        {
            c = 0;
            r++;
        }
        ImageView oImageView = new ImageView(this);
        oImageView.setImageResource(R.drawable.ic_launcher);
        GridLayout.LayoutParams param =new GridLayout.LayoutParams();
        param.height = LayoutParams.WRAP_CONTENT;
        param.width = LayoutParams.WRAP_CONTENT;
        param.rightMargin = 5;
        param.topMargin = 5;
        param.setGravity(Gravity.CENTER);
        param.columnSpec = GridLayout.spec(c);
        param.rowSpec = GridLayout.spec(r);
        oImageView.setLayoutParams (param);
        gridLayout.addView(oImageView);
    }

have look on this image - you can change number of rows and column as you need

Answer:

How about this?

GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
layoutParams.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, item.getRowSpan());
layoutParams.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, item.getColumnSpan());

According to documentation, you should also call setLayoutParams on GridLayout IF you change column or row span AFTER the child views are inserted into GridLayout. You don’t need this if you add them while setting span

Answer:

You could modify GridLayout layout_rowSpan attribute like this:

// View allocated in first row and first column
View child = findViewById(R.id.row0column0);

GridLayout.LayoutParams params =
   new GridLayout.LayoutParams(child.getLayoutParams());

params.rowSpec = GridLayout.spec(0, 2);    // First cell in first row use rowSpan 2.
params.columnSpec = GridLayout.spec(0, 2); // First cell in first column use columnSpan 2.
child.setLayoutParams(params);

I agree documentation needs a little bit improvement in this regard.

Answer:

OK, I spent some hours figuring out what’s going on here. Well, I didn’t find any working way to set columnSpan or rowSpan at runtime.

But I found a solution that works (at least for me):

Java code

private LinearLayout addNewSpannedView(Integer resourceId, ViewGroup rootElement) {
    return (LinearLayout) ((ViewGroup) getLayoutInflater().inflate(resourceId, rootElement, true)).getChildAt(rootElement.getChildCount() - 1);
}
// set columnSpan depending on some logic (gridLayout is the layout to add the view's to -> in my case these are LinearLayouts)
shape = addNewSpannedView(columnSpan == 1 ? R.layout.grid_ll_col_span_1 : R.layout.grid_ll_col_span_2, gridLayout);

grid_ll_col_span_2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/shapeWidth"
    android:layout_height="wrap_content"
    android:layout_columnSpan="2"/>

Hint: It’s very important, that you set the width and height attribute, before inflate() adds the view to the root element (i.e. the parent element).

I hope, someone can use this 😉

Answer:

I am changing column span about 2 cell programmatically and after inflate by this code:

GridLayout.LayoutParams itemLP = (GridLayout.LayoutParams)gridItemV.getLayoutParams();
itemLP.columnSpec = GridLayout.spec(0, 2);
gridItemV.setLayoutParams(itemLP);

the important is call setLayoutParams after change columnSpec
i hope it helps also to you