I need to display a horizontal selection list where the items are spaced out evenly over the view.
For this purpose I would use a FlexLayout and populate its BindableLayout with the input data for selections.
However, the RadioButton refuses to occupy the whole area and setting the WidthRequest manually is not feasable, because the width of the view or the number of selectable options could vary.
Is there something I am missing?
Setting VerticalOptions to Fill at various elements has no effect.
In this picture, the black border shows that the FlexLayout works as expected and is only for display purposes:
Eventually, I would like to achieve the following effect, which is currently done in a hacky way using C# only:

The XAML code for the FlexLayout is as follows:
<FlexLayout Background="Gray"
HeightRequest="100"
JustifyContent="SpaceEvenly"
AlignItems="Stretch">
<!-- Demo items for testing -->
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>1</x:String>
<x:String>2</x:String>
<x:String>3</x:String>
</x:Array>
</BindableLayout.ItemsSource>
<BindableLayout.ItemTemplate>
<DataTemplate>
<!--Border to show that Flexlayout is behaving as expected-->
<Border FlexLayout.Grow="1"
Background="Transparent"
Stroke="Black"
StrokeThickness="2"
StrokeShape="RoundRectangle 10">
<!--This should occupy all the space available-->
<RadioButton Content="{Binding .}" HorizontalOptions="Center" FlexLayout.Grow="1">
<RadioButton.ControlTemplate>
<ControlTemplate>
<Grid BackgroundColor="Cyan">
<Border Background="Orange"
StrokeShape="RoundRectangle 10">
<Label Text="{TemplateBinding Content}"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</Border>
</Grid>
</ControlTemplate>
</RadioButton.ControlTemplate>
</RadioButton>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
Edit: Because it was requested, this shows the "hacky way":
(ContentGrid is an empty Grid defined in XAML)
internal void ReorderItems(IEnumerable<SelectionModel> items)
{
ContentGrid.Clear();
ContentGrid.ColumnDefinitions.Clear();
int counter = 0;
foreach (var item in items)
{
ContentGrid.ColumnDefinitions.Add(new ColumnDefinition());
Frame background = new()
{
HeightRequest = 44,
HorizontalOptions = LayoutOptions.Fill,
CornerRadius = 8,
BorderColor = Colors.Transparent,
Padding = 0,
Style = Resources["NormalStyle"] as Style
};
//Selected item is a bindable property on the control
if (SelectedItem is not null && item.Number == SelectedItem.Number)
background.Style = Resources["SelectedStyle"] as Style;
TapGestureRecognizer tapRecognizer = new()
{
Command = SelectionChangedCommand,
CommandParameter = item,
};
background.GestureRecognizers.Add(tapRecognizer);
Label numberLabel = new()
{
Text = item.Number.ToString(),
TextColor = Color.FromArgb("#6D6D6D"),
FontSize = 14,
VerticalOptions = LayoutOptions.Center,
};
Image defaultImage = new()
{
Source = item.IsLocked ?
_lockImageSource : item.IsFinished ?
_finishedSource : item.IsStarted ?
_startedSource :
_notStartedSource,
HeightRequest = 24,
WidthRequest = 24,
VerticalOptions = LayoutOptions.Center,
};
HorizontalStackLayout centerLayout =
[
numberLabel, defaultImage
];
centerLayout.HorizontalOptions = LayoutOptions.Center;
centerLayout.Spacing = 8;
centerLayout.HeightRequest = 24;
background.Content = centerLayout;
ContentGrid.Add(background, counter, 0);
counter++;
}
}
