class MenuAnchorPosition
private constructor(
internal val xCandidates: MenuPositionScope.() -> IntList,
internal val yCandidates: MenuPositionScope.() -> IntList,
)
Class that determines the position of a menu relative to its anchor.
This allows selecting between standard positioning strategies (such as Above, Below, Start, End, Left, Right) or providing a Custom implementation for complex positioning logic.
Companion Object
Properties
val Above =
MenuAnchorPosition(
xCandidates = {
MenuPosition.xValuesFromCandidates(
listOf(
startToAnchorStart,
endToAnchorEnd,
if (anchorBounds.center.x < windowSize.width / 2) {
leftToWindowLeft
} else {
rightToWindowRight
},
),
anchorBounds,
windowSize,
menuSize.width,
layoutDirection,
)
},
yCandidates = {
MenuPosition.yValuesFromCandidates(
listOf(
bottomToAnchorTop,
topToAnchorBottom,
centerToAnchorTop,
if (anchorBounds.center.y < windowSize.height / 2) {
topToWindowTop
} else {
bottomToWindowBottom
},
),
anchorBounds,
windowSize,
menuSize.height,
)
},
)
Position the menu above its anchor.
The menu's bottom edge is aligned with the anchor's top edge by default. If there is insufficient space, alternative positions (such as below the anchor) will be attempted.
val Below =
MenuAnchorPosition(
xCandidates = {
MenuPosition.xValuesFromCandidates(
listOf(
startToAnchorStart,
endToAnchorEnd,
if (anchorBounds.center.x < windowSize.width / 2) {
leftToWindowLeft
} else {
rightToWindowRight
},
),
anchorBounds,
windowSize,
menuSize.width,
layoutDirection,
)
},
yCandidates = {
MenuPosition.yValuesFromCandidates(
listOf(
topToAnchorBottom,
bottomToAnchorTop,
centerToAnchorTop,
if (anchorBounds.center.y < windowSize.height / 2) {
topToWindowTop
} else {
bottomToWindowBottom
},
),
anchorBounds,
windowSize,
menuSize.height,
)
},
)
Position the menu below its anchor.
The menu's top edge is aligned with the anchor's bottom edge by default. If there is insufficient space, alternative positions (such as above the anchor) will be attempted.
val Left =
MenuAnchorPosition(
xCandidates = {
MenuPosition.xValuesFromCandidates(
listOf(
endToAnchorStart,
startToAnchorEnd,
if (anchorBounds.center.x < windowSize.width / 2) {
leftToWindowLeft
} else {
rightToWindowRight
},
),
anchorBounds,
windowSize,
menuSize.width,
layoutDirection,
)
},
yCandidates = {
MenuPosition.yValuesFromCandidates(
listOf(
topToAnchorTop,
bottomToAnchorBottom,
if (anchorBounds.center.y < windowSize.height / 2) {
topToWindowTop
} else {
bottomToWindowBottom
},
),
anchorBounds,
windowSize,
menuSize.height,
)
},
)
Position the menu to the left of its anchor.
This strategy positions the menu on the left side regardless of the layout direction.
val Right =
MenuAnchorPosition(
xCandidates = {
MenuPosition.xValuesFromCandidates(
listOf(
startToAnchorEnd,
endToAnchorStart,
if (anchorBounds.center.x < windowSize.width / 2) {
leftToWindowLeft
} else {
rightToWindowRight
},
),
anchorBounds,
windowSize,
menuSize.width,
layoutDirection,
)
},
yCandidates = {
MenuPosition.yValuesFromCandidates(
listOf(
topToAnchorTop,
bottomToAnchorBottom,
if (anchorBounds.center.y < windowSize.height / 2) {
topToWindowTop
} else {
bottomToWindowBottom
},
),
anchorBounds,
windowSize,
menuSize.height,
)
},
)
Position the menu to the right of its anchor.
This strategy positions the menu on the right side regardless of the layout direction.
val Start =
MenuAnchorPosition(
xCandidates = {
MenuPosition.xValuesFromCandidates(
listOf(
endToAnchorStart,
startToAnchorEnd,
if (anchorBounds.center.x < windowSize.width / 2) {
leftToWindowLeft
} else {
rightToWindowRight
},
),
anchorBounds,
windowSize,
menuSize.width,
layoutDirection,
)
},
yCandidates = {
MenuPosition.yValuesFromCandidates(
listOf(
topToAnchorTop,
bottomToAnchorBottom,
if (anchorBounds.center.y < windowSize.height / 2) {
topToWindowTop
} else {
bottomToWindowBottom
},
),
anchorBounds,
windowSize,
menuSize.height,
)
},
)
Position the menu to the start of its anchor.
In LTR layouts, this positions the menu on the left side of the anchor. In RTL layouts, this positions the menu on the right side of the anchor.
val End =
MenuAnchorPosition(
xCandidates = {
MenuPosition.xValuesFromCandidates(
listOf(
startToAnchorEnd,
endToAnchorStart,
if (anchorBounds.center.x < windowSize.width / 2) {
leftToWindowLeft
} else {
rightToWindowRight
},
),
anchorBounds,
windowSize,
menuSize.width,
layoutDirection,
)
},
yCandidates = {
MenuPosition.yValuesFromCandidates(
listOf(
topToAnchorTop,
bottomToAnchorBottom,
if (anchorBounds.center.y < windowSize.height / 2) {
topToWindowTop
} else {
bottomToWindowBottom
},
),
anchorBounds,
windowSize,
menuSize.height,
)
},
)
Position the menu to the end of its anchor.
In LTR layouts, this positions the menu on the right side of the anchor. In RTL layouts, this positions the menu on the left side of the anchor.
Methods
fun Custom(
xCandidates: MenuPositionScope.() -> IntList,
yCandidates: MenuPositionScope.() -> IntList,
) = MenuAnchorPosition(xCandidates, yCandidates)
Create a custom positioning strategy by providing lambda functions for calculating candidate positions for the x and y axes. Note that candidate positioning coordinates are calculated relative to the window bounds.
Parameters
| xCandidates | Lambda that determines the list of candidate x coordinates for the menu relative to the window bounds. |
| yCandidates | Lambda that determines the list of candidate y coordinates for the menu relative to the window bounds. |