Skip to content

Derive grid column count from the width the list is given - #17542

Open
sandbranch wants to merge 1 commit into
nextcloud:masterfrom
sandbranch:grid-columns-follow-width
Open

Derive grid column count from the width the list is given#17542
sandbranch wants to merge 1 commit into
nextcloud:masterfrom
sandbranch:grid-columns-follow-width

Conversation

@sandbranch

Copy link
Copy Markdown

Addresses part of the grid item of #6769 ("span list/grid view across whole area").

Problem

The number of grid columns comes straight from the stored zoom preference and never looks at how wide the window actually is, so a phone in portrait and a tablet in landscape both show the same three columns. onConfigurationChanged only ever clamps the count downwards:

if (isGridEnabled && columnsCount > maxColumnSize) {
    (recyclerView?.layoutManager as GridLayoutManager).spanCount = maxColumnSize
}

so rotating to landscape raises the limit but never adds a column.

Fix

Add a GridLayoutManager that works out its own column count from the width it is given during layout, and hand it a target column width instead of a column count. The target is a dimension resource (grid_item_default_width, 140dp), so it can be adjusted per screen size later without touching this code.

The width has to be read during layout. The display metrics are not a usable substitute: they describe the display rather than the space the list occupies, they are not yet meaningful while the view is being created, and during a rotation they can still describe the previous orientation. I tried them first and got a portrait grid laid out to the width of a landscape screen (7 columns instead of 3), which is what prompted the layout-time approach.

Pinch to zoom keeps working and is still persisted. It now sets how large the cells are rather than a fixed column count, so a zoom level chosen in portrait carries over to landscape instead of being lost.

Testing

Measured on real devices, with the resolved width and column count logged:

Device Orientation Before After
Samsung S23 (384dp) portrait 3 3
Samsung S23 landscape 3 6
Lenovo Tab P11 Pro 2nd gen (768dp) portrait 3 5
Lenovo Tab P11 Pro 2nd gen (1280dp) landscape 3 9

The 140dp default was chosen so that a phone in portrait stays at three columns, i.e. existing phone users see no change at all; only wider windows gain columns.

The number of grid columns came straight from the stored zoom
preference and never looked at how wide the window actually is, so a
phone in portrait and a tablet in landscape both showed the same three
columns. onConfigurationChanged only ever clamped the count downwards,
which meant rotating to landscape raised the limit but never added a
column.

Add a GridLayoutManager that works out its own column count from the
width it is given during layout, and hand it a target column width
instead of a column count. The target width is a dimension resource, so
it can be adjusted per screen size later without touching this code.

The width has to be read during layout. The display metrics are not a
usable substitute: they describe the display rather than the space the
list occupies, they are not yet meaningful while the view is being
created, and during a rotation they can still describe the previous
orientation, which produced a portrait grid laid out to the width of a
landscape screen.

Pinch to zoom keeps working and is still persisted. It now sets how
large the cells are rather than a fixed column count, so a zoom level
chosen in portrait carries over to landscape instead of being lost.

Addresses part of the grid item of nextcloud#6769.

Signed-off-by: David Sandquist <sandquist@gmail.com>
This was referenced Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant