GridLayout and Row/Column Span Woe
Solution 1
It feels pretty hacky, but I managed to get the correct look by adding an extra column and row beyond what is needed. Then I filled the extra column with a Space in each row defining a height and filled the extra row with a Space in each col defining a width. For extra flexibility, I imagine these Space sizes could be set in code to provide something similar to weights. I tried to add a screenshot, but I do not have the reputation necessary.
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="9"
android:orientation="horizontal"
android:rowCount="8" >
<Button
android:layout_columnSpan="2"
android:layout_gravity="fill"
android:layout_rowSpan="2"
android:text="1" />
<Button
android:layout_columnSpan="2"
android:layout_gravity="fill_horizontal"
android:text="2" />
<Button
android:layout_gravity="fill_vertical"
android:layout_rowSpan="4"
android:text="3" />
<Button
android:layout_columnSpan="3"
android:layout_gravity="fill"
android:layout_rowSpan="2"
android:text="4" />
<Button
android:layout_columnSpan="3"
android:layout_gravity="fill_horizontal"
android:text="5" />
<Button
android:layout_columnSpan="2"
android:layout_gravity="fill_horizontal"
android:text="6" />
<Space
android:layout_width="36dp"
android:layout_column="0"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="1"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="2"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="3"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="4"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="5"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="6"
android:layout_row="7" />
<Space
android:layout_width="36dp"
android:layout_column="7"
android:layout_row="7" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="0" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="1" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="2" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="3" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="4" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="5" />
<Space
android:layout_height="36dp"
android:layout_column="8"
android:layout_row="6" />
</GridLayout>
Solution 2
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:columnCount="8"
android:rowCount="7" >
<TextView
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_columnSpan="2"
android:layout_rowSpan="2"
android:background="#a30000"
android:gravity="center"
android:text="1"
android:textColor="@android:color/white"
android:textSize="20dip" />
<TextView
android:layout_width="50dip"
android:layout_height="25dip"
android:layout_columnSpan="2"
android:layout_rowSpan="1"
android:background="#0c00a3"
android:gravity="center"
android:text="2"
android:textColor="@android:color/white"
android:textSize="20dip" />
<TextView
android:layout_width="25dip"
android:layout_height="100dip"
android:layout_columnSpan="1"
android:layout_rowSpan="4"
android:background="#00a313"
android:gravity="center"
android:text="3"
android:textColor="@android:color/white"
android:textSize="20dip" />
<TextView
android:layout_width="75dip"
android:layout_height="50dip"
android:layout_columnSpan="3"
android:layout_rowSpan="2"
android:background="#a29100"
android:gravity="center"
android:text="4"
android:textColor="@android:color/white"
android:textSize="20dip" />
<TextView
android:layout_width="75dip"
android:layout_height="25dip"
android:layout_columnSpan="3"
android:layout_rowSpan="1"
android:background="#a500ab"
android:gravity="center"
android:text="5"
android:textColor="@android:color/white"
android:textSize="20dip" />
<TextView
android:layout_width="50dip"
android:layout_height="25dip"
android:layout_columnSpan="2"
android:layout_rowSpan="1"
android:background="#00a9ab"
android:gravity="center"
android:text="6"
android:textColor="@android:color/white"
android:textSize="20dip" />
</GridLayout>
</RelativeLayout>
Solution 3
You have to set both layout_gravity and layout_columntWeight on your columns
<android.support.v7.widget.GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:text="سوم شخص"
app:layout_gravity="fill_horizontal"
app:layout_columnWeight="1"
/>
<TextView android:text="دوم شخص"
app:layout_gravity="fill_horizontal"
app:layout_columnWeight="1"
/>
<TextView android:text="اول شخص"
app:layout_gravity="fill_horizontal"
app:layout_columnWeight="1"
/>
</android.support.v7.widget.GridLayout>
Solution 4
Android Support V7 GridLayout library makes excess space distribution easy by accommodating the principle of weight. To make a column stretch, make sure the components inside it define a weight or a gravity. To prevent a column from stretching, ensure that one of the components in the column does not define a weight or a gravity. Remember to add dependency for this library. Add com.android.support:gridlayout-v7:25.0.1 in build.gradle.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="2"
app:rowCount="2">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="First"
app:layout_columnWeight="1"
app:layout_rowWeight="1" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="Second"
app:layout_columnWeight="1"
app:layout_rowWeight="1" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="Third"
app:layout_columnWeight="1"
app:layout_rowWeight="1" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
app:layout_columnWeight="1"
app:layout_rowWeight="1"
android:text="fourth"/>
</android.support.v7.widget.GridLayout>
Solution 5
Starting from API 21, the GridLayout now supports the weight like LinearLayout. For details please see the link below:
![CommonsWare](https://i.stack.imgur.com/wDnd8.png?s=256&g=1)
CommonsWare
Mark Murphy, founder of CommonsWare, writes a lot. Books From 2008 through 2021, Mark wrote a series of books on Android app development. These books are now available for free download from the CommonsWare site. His most recent books have been focused on second-generation Android app development (Kotlin and the Android Jetpack): Elements of Android Jetpack, a new introductory book on Android app development, focused on second-generation techniques. Exploring Android, a series of step-by-step tutorials for building an Android app from scratch. This book demonstrates app development using Kotlin, coroutines, and the Jetpack libraries. Elements of Android Room, to help you incorporate Google's reactive object wrapper around SQLite. Elements of Android R, to help you deal with the changes introduced by Android 11 (code-named "R"). It covers everything from scoped storage changes to data access auditing to sharing UIs between apps to bubbles. Elements of Kotlin, a guide to the Kotlin programming language, which is rapidly gaining in popularity for Android app development. Elements of Kotlin Coroutines, exploring Kotlin's new first-class reactive programming system. In the beginning, Android development was focused on Java and, partially, on the Android Support Library. Mark's earliest books share that focus: The Busy Coder's Guide to Android Development, the first and largest book on Android app programming Android's Architecture Components GraphQL and Android Things Other Than Books He runs the jetc.dev weekly newsletter for Jetpack Compose. Heck, he even has a blog. All code in Stack Overflow questions, answers, or comments written by Mark Murphy are hereby licensed under the Apache Software License 2.0, unless otherwise noted where that code appears on Stack Overflow.
Updated on November 25, 2020Comments
-
CommonsWare over 3 years
The Android Developers Blog post introducing
GridLayout
shows this diagram of how spans impact automatic index allocation:I am attempting to actually implement that using a
GridLayout
. Here is what I have so far:<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.commonsware.android.gridlayout" android:layout_width="fill_parent" android:layout_height="fill_parent" app:orientation="horizontal" app:columnCount="8"> <Button app:layout_columnSpan="2" app:layout_rowSpan="2" android:layout_gravity="fill_horizontal" android:text="@string/string_1"/> <Button app:layout_columnSpan="2" android:layout_gravity="fill_horizontal" android:text="@string/string_2"/> <Button app:layout_rowSpan="4" android:text="@string/string_3"/> <Button app:layout_columnSpan="3" app:layout_rowSpan="2" android:layout_gravity="fill_horizontal" android:text="@string/string_4"/> <Button app:layout_columnSpan="3" android:layout_gravity="fill_horizontal" android:text="@string/string_5"/> <Button app:layout_columnSpan="2" android:layout_gravity="fill_horizontal" android:text="@string/string_6"/> <android.support.v7.widget.Space app:layout_column="0" android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> <android.support.v7.widget.Space android:layout_width="36dp" /> </android.support.v7.widget.GridLayout>
I had to introduce the
<Space>
elements to ensure each column had a minimum width, otherwise, I would have a bunch of zero-width columns.However, even with them, I get this:
Notably:
Despite
android:layout_gravity="fill_horizontal"
, my widgets with column spans do not fill the spanned columnsDespite the
android:layout_rowSpan
values, nothing spans rows
Can anyone reproduce the diagram from the blog post using a
GridLayout
?Thanks!
-
CommonsWare almost 12 yearsThanks! What's interesting is that if I switch to the
GridLayout
from the Android Support package, the layout breaks, suggesting that the two are not completely compatible. Also, I am really hoping that there's a way to do this that does not involve hard-wiring sizes of the widgets. I'll let this roll for a bit, to see what other answers come in (if any), but I'll accept yours if nothing better shows up. Thanks again! -
CommonsWare almost 12 years"if I switch to the GridLayout from the Android Support package, the layout breaks" -- actually, that was my fault, not converting the required
android:
attributes toapp:
ones, using the backport's XML namespace. It does work with the backport. -
HandlerExploit almost 12 yearsI found a way to have some of them dynamically size but its only if the full width of the columns or rows are already defined by adjacent views. I don't think that they work like weights do and distribute the space equally depending on the spans defined. Its not perfect but it works perfectly for what I need in my current project.
-
CommonsWare almost 12 yearsWell, IMHO that's incrementally less hacky than the other solution presented to date -- at least here, the hard-wired sizes are in the
Space
elements. I added a screenshot for future readers. Thanks! -
curioustechizen almost 12 yearsWhy is the
rowCount
set to 8? We need 4 rows (the size of the largestrowSpan
) plus the extra one forSpace
so that should be 5. What am I missing? -
kturney almost 12 yearsI just went with the row and column counts from the picture in the original question (which is itself from an Android dev blog post). I then added 1 to the row and column counts to make room for the outside border Spaces. It should work fine with just 5 rows as well.
-
Bondax over 11 yearsWell, your example is more like an AbsoluteLayout's aproach mixed with one for a RelativeLayout, isn't it? This is neither dynamic nor portable. Why exactly do you need a GridLayout for this? Anyways, GridLayout is, imho, either broken or unfinished...
-
HandlerExploit over 11 years@Bondax This implementation clearly defines the grid item in both height, width, column width, and column span. The grid layout will float your grid items within the confined space when different widths are defined to the grid (screen width). This was a requirement for a project and this solved the issue perfectly.
-
HandlerExploit over 11 years@Bondax And if you don't understand, this was supposed to be an oversimplified example because that was what the question asked for, nothing more nothing less.
-
Didia almost 11 yearsI find that this solution only works with
<Gridlayout>
as opposed to<android.support.v7.widget.GridLayout>
-
Lalith B almost 11 yearsall of the above is possible with relativelayout Right ?!!
-
Admin over 8 yearsHow can i set dynamically row_span and column span...it will work?
-
Admin over 8 years
-
Admin over 8 years
-
Red M over 7 yearsWhy do we have orientation set to "Horizontal" inside the gridLayout if this last has child views vertically and horizontally?