Skip to content

Commit 582feb4

Browse files
author
Sven Obser
committed
Add RTL support to Flow Layouts
Fixes google#1073
1 parent b9a44ab commit 582feb4

File tree

1 file changed

+56
-20
lines changed
  • flowlayout/src/main/java/com/google/accompanist/flowlayout

1 file changed

+56
-20
lines changed

flowlayout/src/main/java/com/google/accompanist/flowlayout/Flow.kt

+56-20
Original file line numberDiff line numberDiff line change
@@ -231,40 +231,58 @@ private fun Flow(
231231
placeables[j].mainAxisSize() +
232232
if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
233233
}
234-
val arrangement = if (i < sequences.lastIndex) {
235-
mainAxisAlignment.arrangement
234+
val alignment = if (i < sequences.lastIndex) {
235+
mainAxisAlignment
236236
} else {
237-
lastLineMainAxisAlignment.arrangement
237+
lastLineMainAxisAlignment
238238
}
239-
// TODO(soboleva): rtl support
240-
// Handle vertical direction
239+
241240
val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
242-
with(arrangement) {
243-
arrange(mainAxisLayoutSize, childrenMainAxisSizes, mainAxisPositions)
241+
when (orientation) {
242+
LayoutOrientation.Horizontal -> with(alignment.toHorizontalArrangement()) {
243+
arrange(
244+
mainAxisLayoutSize,
245+
childrenMainAxisSizes,
246+
layoutDirection,
247+
mainAxisPositions
248+
)
249+
}
250+
LayoutOrientation.Vertical -> with(alignment.toVerticalArrangement()) {
251+
arrange(mainAxisLayoutSize, childrenMainAxisSizes, mainAxisPositions)
252+
}
244253
}
254+
245255
placeables.forEachIndexed { j, placeable ->
256+
val crossAxisSize = placeable.crossAxisSize()
246257
val crossAxis = when (crossAxisAlignment) {
247258
FlowCrossAxisAlignment.Start -> 0
248259
FlowCrossAxisAlignment.End ->
249-
crossAxisSizes[i] - placeable.crossAxisSize()
260+
crossAxisSizes[i] - crossAxisSize
250261
FlowCrossAxisAlignment.Center ->
251262
Alignment.Center.align(
252263
IntSize.Zero,
253264
IntSize(
254265
width = 0,
255-
height = crossAxisSizes[i] - placeable.crossAxisSize()
266+
height = crossAxisSizes[i] - crossAxisSize
256267
),
257268
LayoutDirection.Ltr
258269
).y
259270
}
271+
272+
val crossAxisPosition = crossAxisPositions[i] + crossAxis
260273
if (orientation == LayoutOrientation.Horizontal) {
261274
placeable.place(
262275
x = mainAxisPositions[j],
263-
y = crossAxisPositions[i] + crossAxis
276+
y = crossAxisPosition
264277
)
265278
} else {
266279
placeable.place(
267-
x = crossAxisPositions[i] + crossAxis,
280+
x = when (layoutDirection) {
281+
LayoutDirection.Ltr ->
282+
crossAxisPosition
283+
LayoutDirection.Rtl ->
284+
crossAxisLayoutSize - crossAxisPosition - crossAxisSize
285+
},
268286
y = mainAxisPositions[j]
269287
)
270288
}
@@ -274,6 +292,26 @@ private fun Flow(
274292
}
275293
}
276294

295+
private fun FlowMainAxisAlignment.toHorizontalArrangement() =
296+
when (this) {
297+
FlowMainAxisAlignment.Center -> Arrangement.Center
298+
FlowMainAxisAlignment.Start -> Arrangement.Start
299+
FlowMainAxisAlignment.End -> Arrangement.End
300+
FlowMainAxisAlignment.SpaceEvenly -> Arrangement.SpaceEvenly
301+
FlowMainAxisAlignment.SpaceBetween -> Arrangement.SpaceBetween
302+
FlowMainAxisAlignment.SpaceAround -> Arrangement.SpaceAround
303+
}
304+
305+
private fun FlowMainAxisAlignment.toVerticalArrangement() =
306+
when (this) {
307+
FlowMainAxisAlignment.Center -> Arrangement.Center
308+
FlowMainAxisAlignment.Start -> Arrangement.Top
309+
FlowMainAxisAlignment.End -> Arrangement.Bottom
310+
FlowMainAxisAlignment.SpaceEvenly -> Arrangement.SpaceEvenly
311+
FlowMainAxisAlignment.SpaceBetween -> Arrangement.SpaceBetween
312+
FlowMainAxisAlignment.SpaceAround -> Arrangement.SpaceAround
313+
}
314+
277315
/**
278316
* Used to specify how a layout chooses its own size when multiple behaviors are possible.
279317
*/
@@ -294,40 +332,38 @@ public enum class SizeMode {
294332
/**
295333
* Used to specify the alignment of a layout's children, in main axis direction.
296334
*/
297-
public enum class MainAxisAlignment(internal val arrangement: Arrangement.Vertical) {
298-
// TODO(soboleva) support RTl in Flow
299-
// workaround for now - use Arrangement that equals to previous Arrangement
335+
public enum class MainAxisAlignment {
300336
/**
301337
* Place children such that they are as close as possible to the middle of the main axis.
302338
*/
303-
Center(Arrangement.Center),
339+
Center,
304340

305341
/**
306342
* Place children such that they are as close as possible to the start of the main axis.
307343
*/
308-
Start(Arrangement.Top),
344+
Start,
309345

310346
/**
311347
* Place children such that they are as close as possible to the end of the main axis.
312348
*/
313-
End(Arrangement.Bottom),
349+
End,
314350

315351
/**
316352
* Place children such that they are spaced evenly across the main axis, including free
317353
* space before the first child and after the last child.
318354
*/
319-
SpaceEvenly(Arrangement.SpaceEvenly),
355+
SpaceEvenly,
320356

321357
/**
322358
* Place children such that they are spaced evenly across the main axis, without free
323359
* space before the first child or after the last child.
324360
*/
325-
SpaceBetween(Arrangement.SpaceBetween),
361+
SpaceBetween,
326362

327363
/**
328364
* Place children such that they are spaced evenly across the main axis, including free
329365
* space before the first child and after the last child, but half the amount of space
330366
* existing otherwise between two consecutive children.
331367
*/
332-
SpaceAround(Arrangement.SpaceAround);
368+
SpaceAround;
333369
}

0 commit comments

Comments
 (0)