Reputation: 6061
I want to have a 2x2 grid with a buttons inside. This is only ICS so I am trying to use the new GridLayout given.
Here's the XML of my layout:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/favorites_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:rowCount="2"
android:columnCount="2">
<Button
android:text="Cell 0"
android:layout_row="0"
android:layout_column="0"
android:textSize="14dip" />
<Button
android:text="Cell 1"
android:layout_row="0"
android:layout_column="1"
android:textSize="14dip" />
<Button
android:text="Cell 2"
android:layout_row="1"
android:layout_column="0"
android:textSize="14dip" />
<Button
android:text="Cell 3"
android:layout_row="1"
android:layout_column="1"
android:textSize="14dip" />
</GridLayout>
The problem is that my views do not stretch evenly for each row. This causes a lot of extra space to the right of my GridLayout.
I tried setting layout_gravity="fill_horizontal"
but that only applies to the last view on the row. This means Cell 1 stretches all the way to give enough space for Cell 0.
Thoughts on how to tackle this?
Upvotes: 256
Views: 403775
Reputation: 6373
I just made simple grid layout out of grid view and was thinking why I didn't do it before. It's so easy to implement. (I use custom wrapper CSView in example but just change it to View). Ops requirement just works in GridView so I posted it here as answer. So to make stretch evenly justy numColumns:auto_fit android:numColumns=2
for example.
usage:
CSGridLayout(this, R.id.sound_store_grid, SubscriptionUpgradeStoreDialogItem(this),
PresetUpgradeStoreDialogItem(this), MidiUpgradeStoreDialogItem(this))
implementation:
class CSGridLayout(parent: CSActivityView<*>,
viewId: Int,
vararg items: CSView<*>) : CSView<GridView>(parent, viewId) {
private val items = list(items)
private var adapter = Adapter()
init {
view.adapter = adapter
adapter.notifyDataSetChanged()
}
inner class Adapter : BaseAdapter() {
override fun getCount() = items.size
override fun getViewTypeCount() = 1
override fun isEnabled(position: Int) = true
override fun getItem(position: Int) = items[position]
override fun getItemViewType(position: Int) = 0
override fun getItemId(position: Int) = position.toLong()
override fun getView(position: Int, toReuseView: View?, parent: ViewGroup) =
items[position].view
}
}
Upvotes: 0
Reputation: 92
main.xml
<GridLayout
android:id="@+id/grid_related_news"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:padding="3dp"
android:columnCount="2">
</GridLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="0dp"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_columnWeight="1"
android:gravity="center"
android:padding="3dp"
android:layout_gravity="fill_horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="5dp"
app:cardElevation="2dp"
android:layout_margin="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/img_related_news"
android:layout_width="0dp"
android:layout_height="0dp"
android:layoutDirection="rtl"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/light_gray" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#59000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txt_related_news_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:elevation="2dp"
android:fontFamily="@font/yekan_bold"
android:letterSpacing="-0.1"
android:lineSpacingExtra="4dp"
android:maxLines="4"
android:textColor="@color/white"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="@string/lorem_ipsum_sentence" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
java
GridLayout grid_related_news = findViewById(R.id.grid_related_news);
View view = LayoutInflater.from(this).inflate(R.layout.related_item, (ViewGroup) grid_related_news, false);
ImageView img_related_news = view.findViewById(R.id.img_related_news);
...
grid_related_news.addView(view);
You can use this example
Upvotes: 0
Reputation: 1179
Some tips on Grid layout from Trial and error.
match_parent
.It is because Grid layout calculates the height/width of its child, and having the variable height of its own could cause issues in calculation of the exact height.android:useDefaultMargins="true"
if we want children to control their margins.the advantage of first scenarios is we can add any number of children in the group and they all will stretch nicely and evenly. the disadvantage becomes that we get a fixed size group. and children with large content also takes a fixed space.
the advantage of second scenario is that we can add more children and they shall decide the height of group. attaching a nested scroll view on the top of parent will make the whole list of elements scrollable. the disadvantage is that children control the height of group and with variables heights, could cause the whole view to look messy.
if we tweak around a bit, both scenarios could be used for their advantages and their disadvantages could be minimised.
example of first scenario:
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2"
android:useDefaultMargins="true">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="2"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_rowWeight="1"
android:layout_columnSpan="2"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="@color/black" />
<!--
add more elements here with same attributes and they will fit on their own!
-->
</GridLayout>
second scenario:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="HardcodedText"
>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:orientation="horizontal"
android:useDefaultMargins="true"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:text="this is a text"
android:textColor="@color/white"
android:layout_gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:layout_gravity="fill_horizontal"
android:text="this is something cool. this should be taking more space but it is also controlling the total height of row"
android:textColor="@color/white"
android:gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:layout_gravity="fill_horizontal"
android:text="once the width is determined by any child, the whole column shall take the same height"
android:textColor="@color/white"
android:gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:text="this column can only control how they shall look by layout gravity. this should look like column 0,0 but its taking full row height/width"
android:textColor="@color/white"
android:gravity="center"
android:layout_margin="8dp"
android:background="@color/black"
/>
<!--
-->
</GridLayout>
</FrameLayout>
Upvotes: 1
Reputation: 40810
It can be done by having equal layout_columnWeight
& layout_rowWeight
Layout:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="3">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 0x0"
grid:layout_column="0"
grid:layout_gravity="center"
grid:layout_row="0" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 0x1"
grid:layout_column="1"
grid:layout_gravity="center"
grid:layout_row="0" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 0x2"
grid:layout_column="2"
grid:layout_gravity="center"
grid:layout_row="0" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 1x0"
grid:layout_column="0"
grid:layout_gravity="center"
grid:layout_row="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 1x1"
grid:layout_column="1"
grid:layout_gravity="center"
grid:layout_row="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 1x2"
grid:layout_column="2"
grid:layout_gravity="center"
grid:layout_row="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 2x0"
grid:layout_column="0"
grid:layout_gravity="center"
grid:layout_row="2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 2x1"
grid:layout_column="1"
grid:layout_gravity="center"
grid:layout_row="2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 2x2"
grid:layout_column="2"
grid:layout_gravity="center"
grid:layout_row="2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 3x0"
grid:layout_column="0"
grid:layout_gravity="center"
grid:layout_row="3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 3x1"
grid:layout_column="1"
grid:layout_gravity="center"
grid:layout_row="3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
android:gravity="center"
android:text="item 3x2"
grid:layout_column="2"
grid:layout_gravity="center"
grid:layout_row="3" />
</GridLayout>
Result
Upvotes: 0
Reputation: 4180
UPDATE: Weights are supported as of API 21. See PaulT's answer for more details.
There are limitations when using the GridLayout, the following quote is taken from the documentation.
"GridLayout does not provide support for the principle of weight, as defined in weight. In general, it is not therefore possible to configure a GridLayout to distribute excess space in non-trivial proportions between multiple rows or columns ... For complete control over excess space distribution in a row or column; use a LinearLayout subview to hold the components in the associated cell group."
Here is a small example that uses LinearLayout subviews. (I used Space Views that takes up unused area and pushes the buttons into desired position.)
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="1"
>
<TextView
android:text="2x2 button grid"
android:textSize="32dip"
android:layout_gravity="center_horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:orientation="horizontal">
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="Button 2" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="Button 4" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</GridLayout>
Upvotes: 84
Reputation: 760
For me, I just changed layout_width
and layout_height
to wrap_content
and set layout_gravity
to center_horizontal
:
<GridLayout
android:id="@+id/gridLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:columnCount="2"
android:rowCount="4">
Upvotes: 0
Reputation: 389
Here's an example
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GridMenuActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="vertical"
android:weightSum="10">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_weight="2"
android:background="@drawable/oval_background">
<ImageView
android:id="@+id/imageView6"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerInParent="true"
android:layout_margin="5dp"
app:srcCompat="@mipmap/dmm_logo" />
</RelativeLayout>
<GridLayout
android:id="@+id/mainGrid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="8"
android:alignmentMode="alignBounds"
android:columnCount="2"
android:columnOrderPreserved="true"
android:padding="5dp"
android:rowCount="5">
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_rowWeight="1"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_dashboard" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dashboard"
android:textAlignment="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Add Entry"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_rowWeight="1"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_sell" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Sale Forecast"
android:textAlignment="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Upcoming Milk Requirement"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_rowWeight="1"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_seller" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Sellers"
android:textAlignment="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Milk Providers"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_rowWeight="1"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_shopping" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Purchasers"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Milk Consumers"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Row 2 -->
<!-- Column 1 -->
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_rowWeight="1"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_advance" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Advance"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Advance Payments"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Column 2 -->
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_rowWeight="1"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_reciever" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Due"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Pending Payments"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_rowWeight="1"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_transaction" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Transactions"
android:layout_gravity="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Payments Detalis"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_rowWeight="1"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_sell" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sell Product"
android:layout_gravity="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Ghee, Curd etc."
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_rowWeight="1"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_purchase_report" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Purchases"
android:layout_gravity="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Milk Purchase Entries"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_rowWeight="1"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_margin="16dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_sale_report" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sales"
android:layout_gravity="center"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Milk Sale Entries"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</GridLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Perfect for me. I hope it helps you too
Upvotes: 1
Reputation: 1244
Appcompat21 GridLayout
has the column and row weights which can be used like below to evenly create each grid item in the gridlayout like the image above.
<android.support.v7.widget.GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
grid:alignmentMode="alignBounds"
grid:columnCount="4" >
<Button android:layout_width="0dp"
style="?buttonStyle"
android:layout_height="0dp"
android:text="-1"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
grid:layout_gravity="fill" />
...
</<android.support.v7.widget.GridLayout>
Upvotes: 82
Reputation: 799
<GridLayout
android:layout_width="match_parent"
android:layout_weight="3"
android:columnCount="2"
android:padding="10dp"
android:rowCount="3"
android:background="@drawable/background_down"
android:layout_height="0dp">
<androidx.cardview.widget.CardView
android:layout_height="0dp"
android:layout_width="0dp"
android:layout_columnWeight="1"
android:layout_rowWeight="1"
android:layout_margin="10dp"
android:elevation="10dp"
app:cardCornerRadius="15dp"
>
<LinearLayout
android:weightSum="3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_weight="2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:src="@drawable/user" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Users"
android:textSize="16sp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_height="0dp"
android:layout_width="0dp"
android:layout_columnWeight="1"
android:layout_rowWeight="1"
android:layout_margin="10dp"
android:elevation="10dp"
app:cardCornerRadius="15dp"
>
<LinearLayout
android:weightSum="3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_weight="2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:src="@drawable/addusers" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Users"
android:textSize="16sp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_height="0dp"
android:layout_width="0dp"
android:layout_columnWeight="1"
android:layout_rowWeight="1"
android:layout_margin="10dp"
android:elevation="10dp"
app:cardCornerRadius="15dp"
>
<LinearLayout
android:weightSum="3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_weight="2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:src="@drawable/newspaper" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Report"
android:textSize="16sp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_height="0dp"
android:layout_width="0dp"
android:layout_columnWeight="1"
android:layout_rowWeight="1"
android:layout_margin="10dp"
android:elevation="10dp"
app:cardCornerRadius="5dp"
>
<LinearLayout
android:weightSum="3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_weight="2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:src="@drawable/settings" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Settings"
android:textSize="16sp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</GridLayout>
you can find the whole tutorials here, Android Grid Layout With CardView and OnItemClickListener
Upvotes: 0
Reputation: 466
i have same problem and i think just set width and height programmatically :
set width of button's with metrics.widthPixels / 2 metrics is object of DisplayMetrics.
GridLayout gridLayout=findViewById(R.id.grid);
for (int i = 0; i <gridLayout.getChildCount() ; i++) {
View view= gridLayout.getChildAt(i);
if(view instanceof Button){
Button btn = (Button) view;
btn.setWidth(200);//metrics.widthPixels / 2
btn.setHeight(200);//metrics.heightPixels / 7
}
}
Upvotes: 2
Reputation: 11
This is the code for more default application without the buttons, this is very handy for me
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="1"
>
<TextView
android:text="2x2 button grid"
android:textSize="32dip"
android:layout_gravity="center_horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Naam" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@{viewModel.selectedItem.test2}" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nummer" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@{viewModel.selectedItem.test}" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</GridLayout>
Upvotes: 1
Reputation: 14510
Result :
Try something like this :
final int MAX_COLUMN = gridView.getColumnCount(); //5
final int MAX_ROW = gridView.getRowCount(); //7
final int itemsCount = MAX_ROW * MAX_COLUMN; //35
int row = 0, column = 0;
for (int i = 0; i < itemsCount; i++) {
ImageView view = new ImageView(this);
//Just to provide alternate colors
if (i % 2 == 0) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.GREEN);
}
GridLayout.LayoutParams params = new GridLayout.LayoutParams(GridLayout.spec(row, 1F), GridLayout.spec(column, 1F));
view.setLayoutParams(params);
gridView.addView(view);
column++;
if (column >= MAX_COLUMN) {
column = 0;
row++;
}
}
If you want specific width and height for your cells, then use :
params.width = 100; // Your width
params.height = 100; //your height
Upvotes: 3
Reputation: 353
Here you are :
Button button = new Button(this);
// weight = 1f , gravity = GridLayout.FILL
GridLayout.LayoutParams param= new GridLayout.LayoutParams(GridLayout.spec(
GridLayout.UNDEFINED,GridLayout.FILL,1f),
GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f));
// Layout_height = 0 ,Layout_weight = 0
params.height =0;
params.width = 0;
button.setLayoutParams(param);
Upvotes: 4
Reputation: 1141
Try adding the following to your GridLayout spec. That should work.
android:useDefaultMargins="true"
Upvotes: 16
Reputation: 8945
This is the right answer
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/favorites_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:rowCount="2"
android:columnCount="2">
<Button
android:text="Cell 0"
android:layout_row="0"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_rowWeight="1"
android:textSize="14dip"
/>
<Button
android:text="Cell 1"
android:layout_row="0"
android:layout_column="1"
android:textSize="14dip"
android:layout_columnWeight="1"
android:layout_rowWeight="1"/>
<Button
android:text="Cell 2"
android:layout_row="1"
android:layout_column="0"
android:textSize="14dip"
android:layout_columnWeight="1"
android:layout_rowWeight="1"/>
<Button
android:text="Cell 3"
android:layout_row="1"
android:layout_column="1"
android:textSize="14dip"
android:layout_columnWeight="1"
android:layout_rowWeight="1"/>
</GridLayout>
Upvotes: 19
Reputation: 2515
In my case I was adding the buttons dynamically so my solution required some XML part and some Java part. I had to find and mix solutions from a few different places and thought I will share it here so someone else looking for the similar solution might find it helpful.
First part of my layout file XML...
<android.support.v7.widget.GridLayout
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:id="@+id/gl_Options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
grid:useDefaultMargins="true">
</android.support.v7.widget.GridLayout>
grid:useDefaultMargins="true"
is not required but I added because that looked better to me, you may apply other visual affects (e.g. padding) as mentioned in some answers here. Now for the buttons as I have to add them dynamically. Here is the Java part of my code to make these buttons, I am including only those lines related to this context. Assume I have to make buttons from as many myOptions
are available to my code and I am not copying the OnClickListener code as well.
import android.support.v7.widget.GridLayout; //Reference to Library
public class myFragment extends Fragment{
GridLayout gl_Options;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
gl_AmountOptions = (GridLayout)view.findViewById( R.id.gl_AmountOptions );
...
gl_Options.removeAllViews(); // Remove all existing views
gl_AmountOptions.setColumnCount( myOptions.length <= 9 ? 3: 4 ); // Set appropriate number of columns
for( String opt : myOptions ) {
GridLayout.LayoutParams lParams = new GridLayout.LayoutParams( GridLayout.spec( GridLayout.UNDEFINED, 1f), GridLayout.spec( GridLayout.UNDEFINED, 1f));
// The above defines LayoutParameters as not specified Column and Row with grid:layout_columnWeight="1" and grid:layout_rowWeight="1"
lParams.width = 0; // Setting width to "0dp" so weight is applied instead
Button b = new Button(this.getContext());
b.setText( opt );
b.setLayoutParams(lParams);
b.setOnClickListener( myClickListener );
gl_Options.addView( b );
}
}
}
As we are using GridLayout from support library and not the standard GridLayout, we have to tell grade about that in YourProject.grade
file.
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
...
compile 'com.android.support:gridlayout-v7:23.4.0'
}
Upvotes: 7
Reputation: 3104
Starting in API 21 without v7 support library with ScrollView:
XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
>
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_columnWeight="1"
android:gravity="center"
android:layout_gravity="fill_horizontal"
android:background="@color/colorAccent"
android:text="Tile1" />
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_columnWeight="1"
android:gravity="center"
android:layout_gravity="fill_horizontal"
android:background="@color/colorPrimaryDark"
android:text="Tile2" />
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_columnWeight="1"
android:gravity="center"
android:layout_gravity="fill_horizontal"
android:background="@color/colorPrimary"
android:text="Tile3" />
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_columnWeight="1"
android:gravity="center"
android:layout_gravity="fill_horizontal"
android:background="@color/colorAccent"
android:text="Tile4" />
</GridLayout>
</ScrollView>
Upvotes: 58
Reputation: 4296
Starting in API 21 the notion of weight was added to GridLayout. To support older android devices, you can use the GridLayout from the v7 support library.
The following XML gives an example of how you can use weights to fill the screen width.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:id="@+id/choice_grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:padding="4dp"
grid:alignmentMode="alignBounds"
grid:columnCount="2"
grid:rowOrderPreserved="false"
grid:useDefaultMargins="true">
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
grid:layout_columnWeight="1"
grid:layout_gravity="fill_horizontal"
android:gravity="center"
android:background="#FF33B5E5"
android:text="Tile1" />
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
grid:layout_columnWeight="1"
grid:layout_gravity="fill_horizontal"
android:gravity="center"
android:background="#FF33B5E5"
android:text="Tile2" />
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
grid:layout_columnWeight="1"
grid:layout_gravity="fill_horizontal"
android:gravity="center"
android:background="#FF33B5E5"
android:text="Tile3" />
<TextView
android:layout_width="0dp"
android:layout_height="100dp"
grid:layout_columnWeight="1"
grid:layout_gravity="fill_horizontal"
android:gravity="center"
android:background="#FF33B5E5"
android:text="Tile4" />
</android.support.v7.widget.GridLayout>
Upvotes: 351
Reputation: 501
You can make this lot faster by overriding ViewGroup onLayout method. This is my universal solution:
package your.app.package;
import android.content.Context;
import android.view.ViewGroup;
public class GridLayout extends ViewGroup {
public GridLayout(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int columns = 2;//edit this if you need different grid
final int rows = 2;
int children = getChildCount();
if (children != columns * rows)
throw new IllegalStateException("GridLayout must have " + columns * rows + " children");
int width = getWidth();
int height = getHeight();
int viewWidth = width / columns;
int viewHeight = height / rows;
int rowIndex = 0;
int columnIndex = 0;
for (int i = 0; i < children; i++) {
getChildAt(i).layout(viewWidth * columnIndex, viewHeight * rowIndex, viewWidth * columnIndex + viewWidth, viewHeight * rowIndex + viewHeight);
columnIndex++;
if (columnIndex == columns) {
columnIndex = 0;
rowIndex++;
}
}
}
}
EDIT: Don't forget match_parent for children!
android:layout_width="match_parent"
android:layout_height="match_parent"
Upvotes: 5
Reputation: 1716
This is a fairly old question, but obviously of interest to a lot of people. For a simple layout of 4 buttons like this, it seems that a TableLayout is the easiest way to accomplish the desired result.
Here's some example code showing the first 2 rows of a table with 6 columns spanning the width of its parent. The LinearLayout and ImageView in each cell are used to allow for the "turning on and off" of an image within the cell while having the color of the cell persist.
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1,2,3,4,5,6"
android:background="@drawable/vertical_radio_button_background"
android:padding="2dp">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/brown"
android:tag="13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="1"
android:background="@color/brown">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/maraschino"
android:tag="9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="2"
android:background="@color/maraschino">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/cayenne"
android:tag="22"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="3"
android:background="@color/cayenne">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/maroon"
android:tag="18"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="4"
android:background="@color/maroon">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/plum"
android:tag="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="5"
android:background="@color/plum">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/eggplant"
android:tag="15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="6"
android:background="@color/eggplant">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/plum2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="1"
android:background="@color/plum">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/lavender"
android:tag="14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="2"
android:background="@color/lavender">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/carnation"
android:tag="16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="3"
android:background="@color/carnation">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/light_pink"
android:tag="23"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="4"
android:background="@color/light_pink">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/strawberry"
android:tag="10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="5"
android:background="@color/strawberry">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/magenta"
android:tag="20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="1dp"
android:layout_column="6"
android:background="@color/magenta">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/selected_check"
android:visibility="invisible"/>
</LinearLayout>
</TableRow>
</TableLayout>
Upvotes: 1
Reputation: 321
The best solution I could find is to use a linear layout(horizontal) for each row you want and within it assign the button (cell) width to 0dp and the weight to 1. For each of the linear layouts(rows) assign the height to 0dp and the weight to 1. Find the code below- also android:layout_gravity="center_vertical" is used to align the buttons in a row in case they contain variable length text. Use of 0dp and weight it a pretty neat yet not so well known trick.
<LinearLayout
android:id="@+id/parent_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_bue_3d"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/layout_row1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:clickable="false"
android:layout_gravity="center_vertical"
android:text="ssssssssssssssssssssssssss" />
<Button
android:id="@+id/button2"
style="?android:attr/buttonStyleSmall"
android:clickable="false"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:text="sggggggg" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_row2"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal" >
<Button
android:id="@+id/button3"
style="?android:attr/buttonStyleSmall"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:text="s" />
<Button
android:id="@+id/button4"
style="?android:attr/buttonStyleSmall"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:clickable="false"
android:layout_gravity="center_vertical"
android:text="s" />
</LinearLayout>
</LinearLayout>
Upvotes: 3
Reputation: 796
Here is what I did and I'm happy to say that this worked for me. I too wanted a 2x2, 3x3 etc. grid of items to cover the entire screen. Gridlayouts do not adhere to the width of the screen. LinearLayouts kind of work but you cant use nested weights.
The best option for me was to use Fragments I used this tutorial to get started with what I wanted to do.
Here is some code:
Main Activity:
public class GridHolderActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_6);
}
}
activity_main_6 XML (inflates 3 fragments)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/frag1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name=".TwoHorizontalGridFragment"
tools:layout="@layout/two_horiz" />
<fragment
android:id="@+id/frag2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name=".TwoHorizontalGridFragment"
tools:layout="@layout/two_horiz" />
<fragment
android:id="@+id/frag3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name=".Grid.TwoHorizontalGridFragment"
tools:layout="@layout/two_horiz" />
Base fragment layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_height="match_parent">
<ImageQueue
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/img1"
android:layout_weight="1"/>
<ImageQueue
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/img2"
android:layout_weight="1"/>
</LinearLayout>
Fragment Class (only handles initialization of a custom view) inflates 2 tiles per fragment
public class TwoHorizontalGridFragment extends Fragment {
private View rootView;
private ImageQueue imageQueue1;
private ImageQueue imageQueue2;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
/**
* Inflate the layout for this fragment
*/
rootView = inflater.inflate(
R.layout.two_horiz, container, false);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
imageQueue1 = (ImageQueue)rootView.findViewById(R.id.img1);
imageQueue2 = (ImageQueue)rootView.findViewById(R.id.img2);
imageQueue1.updateFiles();
imageQueue2.updateFiles();
}
}
Thats it!
This is a weird work around to using nested weights, essentially. It gives me a perfect 2x3 grid that fills the entire screen of both my 10 inch tablet and my HTC droid DNA. Let me know how it goes for you!
Upvotes: -2
Reputation: 1734
I wanted to have a centered table with the labels right aligned and the values left aligned. The extra space should be around the table. After much experimenting and not following what the documentation said I should do, I came up with something that works. Here's what I did:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical" >
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="2"
android:orientation="horizontal"
android:useDefaultMargins="true" >
<TextView
android:layout_gravity="right"
android:text="Short label:" />
<TextView
android:id="@+id/start_time"
android:layout_gravity="left"
android:text="Long extended value" />
<TextView
android:layout_gravity="right"
android:text="A very long extended label:" />
<TextView
android:id="@+id/elapsed_time"
android:layout_gravity="left"
android:text="Short value" />
</GridLayout>
This seems to work but the GridLayout shows the message:
"This GridLayout layout or its LinearLayout parent is useless"
Not sure why it is "useless" when it works for me.
I'm not sure why this works or if this is a good idea, but if you try it and can provide a better idea, small improvement or explain why it works (or won't work) I'd appreciate the feedback.
Thanks.
Upvotes: 1
Reputation: 3203
I finally found the solution. As Rotemmiz said, you have to do it dynamically afterwards. This code stretches the buttons to fill the view horizontally, but the same can be done for vertically.
public void fillview(android.support.v7.widget.GridLayout gl)
{
Button buttontemp;
//Stretch buttons
int idealChildWidth = (int) ((gl.getWidth()-20*gl.getColumnCount())/gl.getColumnCount());
for( int i=0; i< gl.getChildCount();i++)
{
buttontemp = (Button) gl.getChildAt(i);
buttontemp.setWidth(idealChildWidth);
}
}
(The 20 is for the internal and external padding and margins. This could be done more universally, but this is far cleaner)
Then it can be called like this:
android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout)findViewById(R.id.buttongrid);
ViewTreeObserver vto = gl.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Override public void onGlobalLayout()
{
android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout) findViewById(R.id.buttongrid);
fillview(gl);
ViewTreeObserver obs = gl.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}});
It must be done with an observer because we need to wait for the view to be drawn before we call the views.
Upvotes: 7
Reputation: 7971
You can set width of every child dynamically:
GridLayout.LayoutParams params = (GridLayout.LayoutParams) child.getLayoutParams();
params.width = (parent.getWidth()/parent.getColumnCount()) -params.rightMargin - params.leftMargin;
child.setLayoutParams(params);
Upvotes: 36