Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This library can be simpler solution for small grid UI.
There are benefits of this library:

- **Similar API to LazyGrid**: The GridLayout's APIs are designed to provide similar development experience to LazyGrid.
- **Easy to implement adaptive grid**: There are _"Fixed"_ and _"Adaptive"_ for grid layout management like LazyGrid.
- **Easy to implement various grid**: There are _"Fixed"_, _"Adaptive"_ and _"FixedSize"_ for grid layout management like LazyGrid.
Like LazyGrid, it eliminates dealing with different screen sizes.
- **Simple to use as a part of LazyList**: The GridLayout is not lazy layout. It can be simply placed in lazy layouts.
If only a portion of the full layout is grid, No need to use LazyGrid with span size for full layout.
Expand Down
48 changes: 45 additions & 3 deletions docs/cell-strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
All grid layout composables take a cell strategy parameter called `SimpleGridCells`.
`SimpleGridCells` defines the number of cells and the size of each cell.

There are 2 types of cell strategy, `Fixed` and `Adaptive`.
They are similar to LazyGrid's `Fixed` and `Adaptive`.
There are several types of cell strategy, `Fixed`, `Adaptive` and `FixedSize`.
They are similar to LazyGrid's `GridCells.Fixed`, `GridCells.Adaptive` and `GridCells.FixedSize`.

## Fixed

Expand Down Expand Up @@ -94,9 +94,51 @@ And each cells will have 1/3 of 400dp (about 133.333dp) width or height.
If the grid size is expanded to 600dp, the number of cells on each line will be changed to 5
and each cell's size will be 120dp.

## FixedSize

`SimpleGridCells.FixedSize` is a cell strategy for as many cells as possible with exact size.

The API of `FixedSize` looks like this:

```kotlin
class FixedSize(
private val size: Dp,
private val fill: Boolean = true
) : SimpleGridCells
```

There is a parameter called `size`. This is the size of each cell should have.
The `size` must be a positive size. If the size is 0 or below, it occurs an exception.
If the `size` is bigger than container's size, the cell will have the same size to the container.

!!! note
For information about `fill` parameter, read [Fill Option](#fill-option) section.

For example, a grid has 400dp width or height and `FixedSize(120.dp)` is applied.

```kotlin
HorizontalGrid(
rows = SimpleGridCells.FixedSize(120.dp),
modifier = Modifier.height(400.dp)
) { /* content */ }

VerticalGrid(
columns = SimpleGridCells.FixedSize(120.dp),
modifier = Modifier.width(400.dp)
) { /* content */ }
```

![fixed-size-example](./images/fixedsize-example.png)

The grid will have 3 cells on each line and the remaining space will not be used.
If the grid size is expanded to 600dp, the number of cells on each line will be changed to 5.

In other case, `FixedSize(300.dp)` for `VerticalGrid(Modifier.width(200.dp))` means that there
will be only one column and the cell will have 200dp width.

## Fill Option

Both `Fixed` and `Adaptive` have a optional parameter named `fill`.
All cell strategy classes have a optional parameter named `fill`.
The `fill` parameter determines that grid's item composable should fill grid cell's size.

When `fill` is true, grid layout forces item composable to have width or height to fit cell's maximum width or height.
Expand Down
Binary file added docs/images/fixedsize-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This library can be simpler solution for small grid UI.
There are benefits of this library:

- **Similar API to LazyGrid**: The GridLayout's APIs are designed to provide similar development experience to LazyGrid.
- **Easy to implement adaptive grid**: There are _"Fixed"_ and _"Adaptive"_ for grid layout management like LazyGrid.
- **Easy to implement various grid**: There are _"Fixed"_, _"Adaptive"_ and _"FixedSize"_ for grid layout management like LazyGrid.
Like LazyGrid, it eliminates dealing with different screen sizes.
- **Simple to use as a part of LazyList**: The GridLayout is not lazy layout. It can be simply placed in lazy layouts.
If only a portion of the full layout is grid, No need to use LazyGrid with span size for full layout.
Expand Down
10 changes: 10 additions & 0 deletions grid/api/android/grid.api
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,13 @@ public final class com/cheonjaeung/compose/grid/SimpleGridCells$Fixed : com/cheo
public fun hashCode ()I
}

public final class com/cheonjaeung/compose/grid/SimpleGridCells$FixedSize : com/cheonjaeung/compose/grid/SimpleGridCells {
public static final field $stable I
public synthetic fun <init> (FZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (FZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun calculateCrossAxisCellSizes (Landroidx/compose/ui/unit/Density;II)Ljava/util/List;
public fun equals (Ljava/lang/Object;)Z
public fun fillCellSize ()Z
public fun hashCode ()I
}

10 changes: 10 additions & 0 deletions grid/api/jvm/grid.api
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,13 @@ public final class com/cheonjaeung/compose/grid/SimpleGridCells$Fixed : com/cheo
public fun hashCode ()I
}

public final class com/cheonjaeung/compose/grid/SimpleGridCells$FixedSize : com/cheonjaeung/compose/grid/SimpleGridCells {
public static final field $stable I
public synthetic fun <init> (FZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (FZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun calculateCrossAxisCellSizes (Landroidx/compose/ui/unit/Density;II)Ljava/util/List;
public fun equals (Ljava/lang/Object;)Z
public fun fillCellSize ()Z
public fun hashCode ()I
}

Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,22 @@ private class BoxGridMeasureHelper(
val horizontalSpacingPx = horizontalSpacing.roundToPx()
val verticalSpacingPx = verticalSpacing.roundToPx()

var currentX = 0
var currentY = 0
var currentX = if (layoutDirection == LayoutDirection.Rtl) {
val horizontalSpacingCount = (columnCount - 1).coerceAtLeast(0)
val horizontalSpacingSumPx = horizontalSpacingPx * horizontalSpacingCount
val contentWidth = cellWidthConstraintList.sum() + horizontalSpacingSumPx
measureResult.layoutSize.width.roundToInt() - contentWidth
} else {
0
}
val xPositions = IntArray(columnCount)
val yPositions = IntArray(rowCount)
for (i in 0 until columnCount) {
xPositions[i] = currentX
currentX += cellWidthConstraintList[i] + horizontalSpacingPx
}

var currentY = 0
val yPositions = IntArray(rowCount)
for (i in 0 until rowCount) {
yPositions[i] = currentY
currentY += cellHeightConstraintList[i] + verticalSpacingPx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,67 @@ interface SimpleGridCells {
return hash
}
}

/**
* Make grid to have as many rows or columns as possible and each cell has exactly [size].
* If [size] is bigger than container's size, the cell will have the same size to the container.
*
* For example, `FixedSize(20.dp)` for `VerticalGrid(Modifier.width(66.dp)` means that there
* will be 3 columns and each cell will have 20dp width and 6dp is remained.
*
* In other case, `FixedSize(150.dp)` for `VerticalGrid(Modifier.width(100.dp)` means that there
* will be only one column and the cell will have 100dp width.
*
* @param size The size which each cell should have.
* @param fill When `true`, item composable fill cell's width or height.
*/
@ExperimentalGridApi
class FixedSize(
private val size: Dp,
private val fill: Boolean = true,
) : SimpleGridCells {
init {
if (size <= 0.dp) {
throw IllegalArgumentException("FixedSize size must be a positive, but $size")
}
}

override fun Density.calculateCrossAxisCellSizes(
availableSize: Int,
spacing: Int
): List<Int> {
val cellSize = size.roundToPx()
val availableSizeWithSpacing = availableSize + spacing
val cellSizeWithSpacing = cellSize + spacing

return if (cellSizeWithSpacing < availableSizeWithSpacing) {
val count = if (cellSizeWithSpacing != 0) {
availableSizeWithSpacing / cellSizeWithSpacing
} else {
1
}
return List(count) { cellSize }
} else {
List(1) { availableSize }
}
}

override fun fillCellSize(): Boolean {
return fill
}

override fun equals(other: Any?): Boolean {
if (other !is FixedSize) return false
if (this.size != other.size) return false
if (this.fill != other.fill) return false
return true
}

override fun hashCode(): Int {
var hash = 1
hash = hash * 31 + size.hashCode()
hash = hash * 31 + fill.hashCode()
return hash
}
}
}
Loading