Se o seu aplicativo móvel precisar que uma seção deslizante apareça na parte inferior da tela, verifique o componente .NET MAUI BottomSheet.
Em alguns aplicativos móveis modernos, podemos ver um componente chamado Bottom Sheet em ação, que permite ao usuário deslizar uma seção da parte inferior do aplicativo para exibir ações ou informações sem alterar a tela.
Esse tipo de componente não existe como parte dos controles MAUI nativos do .NET. Felizmente, o conjunto de controles Progress Telerik para .NET MAUI oferece o Folha inferior do .NET MAUI componente, que analisaremos durante este post. Vamos começar!
Descobrindo o componente Telerik .NET MAUI BottomSheet para .NET MAUI
Exploraremos diferentes recursos do componente Bottom Sheet, para o qual mostrarei uma janela criada com código XAML que pode muito bem representar uma seção de um aplicativo real. A seguir, mostrarei como implementar o controle Bottom Sheet para exibir opções de seleção aos usuários na mesma janela.
Criando um projeto de exemplo
Suponha que temos um projeto que permite aos usuários pedir comida em restaurantes por meio de um aplicativo. Para a criação da página XAML, usei diferentes controles do conjunto Telerik UI for .NET MAUI, que permitem a criação rápida de interfaces gráficas personalizadas:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=".2*" />
<RowDefinition Height=".8*" />
Grid.RowDefinitions>
<VerticalStackLayout Padding="25,25,25,0" Spacing="10">
<Label
FontAttributes="Bold"
FontSize="12"
Text="DELIVERY ADDRESS"
TextColor="White" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
Grid.ColumnDefinitions>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="OnAddressTapped" />
Grid.GestureRecognizers>
<Label
x:Name="CurrentAddressLabel"
FontSize="16"
Text="123 Main Street, City"
TextColor="White"
VerticalOptions="Center" />
<Label
Grid.Column="1"
Margin="10,0,0,0"
FontSize="14"
Text="▼"
TextColor="White"
VerticalOptions="Center" />
Grid>
<telerik:RadBorder
Padding="10"
BackgroundColor="#6B5BAF"
CornerRadius="10">
<Grid ColumnDefinitions="Auto,*">
<Label
Margin="0,0,10,0"
FontSize="16"
Text="🔍"
VerticalOptions="Center" />
<telerik:RadEntry
x:Name="StoreSearchEntry"
Grid.Column="1"
BackgroundColor="Transparent"
BorderThickness="0"
ClearButtonVisibility="WhileEditing"
Placeholder="Search a restaurant or dish"
PlaceholderColor="#B8B0D0"
TextColor="White" />
Grid>
telerik:RadBorder>
VerticalStackLayout>
<telerik:RadBorder
Grid.Row="1"
Margin="0,10,0,0"
BackgroundColor="#F2F1F6"
CornerRadius="25,25,0,0">
<telerik:RadCollectionView
x:Name="StoresCollection"
Margin="15"
SelectionChanged="OnStoreSelected"
SelectionMode="Single">
<telerik:RadCollectionView.ItemsLayout>
<telerik:CollectionViewLinearLayout ItemSpacing="15" />
telerik:RadCollectionView.ItemsLayout>
<telerik:RadCollectionView.ItemTemplate>
<DataTemplate>
<Border
Padding="0"
BackgroundColor="White"
StrokeShape="RoundRectangle 15"
StrokeThickness="0">
<Border.Shadow>
<Shadow
Brush="#CFD0D4"
Opacity="0.5"
Radius="10"
Offset="5,5" />
Border.Shadow>
<Grid Padding="0" RowDefinitions="150,Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=".6*" />
<RowDefinition Height=".4*" />
Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".4*" />
<ColumnDefinition Width=".2*" />
<ColumnDefinition Width=".4*" />
Grid.ColumnDefinitions>
<Image
Grid.RowSpan="2"
Grid.ColumnSpan="3"
Aspect="AspectFill"
Source="{Binding Header}" />
<Grid
Grid.Row="1"
Grid.Column="0"
Margin="10,0,0,0"
HeightRequest="70"
HorizontalOptions="Start"
VerticalOptions="End"
WidthRequest="70">
<Border
HeightRequest="65"
HorizontalOptions="Center"
StrokeShape="Ellipse"
StrokeThickness="3"
WidthRequest="65">
<Border.Stroke>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Offset="0.0" Color="#FEFEEF" />
<GradientStop Offset="0.25" Color="#EBD570" />
<GradientStop Offset="0.5" Color="#FF94C3" />
<GradientStop Offset="0.75" Color="#A573E4" />
<GradientStop Offset="1.0" Color="#A9E2EE" />
LinearGradientBrush>
Border.Stroke>
<Image
Aspect="AspectFill"
HorizontalOptions="Center"
Source="{Binding Logo}" />
Border>
Grid>
<Border
Grid.Row="1"
Grid.Column="2"
Margin="0,0,10,10"
Padding="10,5"
BackgroundColor="#F8F8F7"
HeightRequest="35"
HorizontalOptions="Center"
StrokeShape="RoundRectangle 10"
StrokeThickness="0"
VerticalOptions="End"
WidthRequest="70">
<HorizontalStackLayout
HorizontalOptions="Center"
Spacing="8"
VerticalOptions="Center">
<Label
FontSize="14"
Text="⭐"
VerticalOptions="Center" />
<Label
FontAttributes="Bold"
FontSize="14"
Text="{Binding Rating}"
TextColor="Black"
VerticalOptions="Center" />
HorizontalStackLayout>
Border>
Grid>
<VerticalStackLayout
Grid.Row="1"
Padding="15"
Spacing="8">
<Label
FontAttributes="Bold"
FontSize="18"
Text="{Binding Name}"
TextColor="Black" />
<Grid ColumnDefinitions="*,*,*">
<Label
FontSize="13"
Text="{Binding Minimum, StringFormat='${0} min'}"
TextColor="#666666" />
<Label
Grid.Column="1"
FontSize="13"
HorizontalOptions="Center"
Text="{Binding ServiceFee, StringFormat='Fee: ${0}'}"
TextColor="#666666" />
<Label
Grid.Column="2"
FontSize="13"
HorizontalOptions="End"
Text="{Binding DeliveryTime}"
TextColor="#666666" />
Grid>
VerticalStackLayout>
Grid>
Border>
DataTemplate>
telerik:RadCollectionView.ItemTemplate>
telerik:RadCollectionView>
telerik:RadBorder>
Grid>
O resultado é uma bela interface gráfica que mostra alguns restaurantes fictícios, junto com controles adicionais como uma barra de pesquisa e um seletor de endereço físico:

Na captura de tela acima, você pode ver alguns componentes do Telerik usados, como os seguintes:
RadEntry: Para a barra de pesquisa da lojaRadBorder: para melhorar a aparência da barra de pesquisa e dos itens da listaRadCollection: Para exibir a lista de lojas
Na parte superior do aplicativo, coloquei um endereço fictício abaixo do texto Endereço de entrega. Idealmente, os usuários deveriam poder selecionar um endereço de entrega diferente, se necessário, sem sair da tela atual. Este é um excelente caso de uso para uma Folha Inferior.
Conhecendo o componente Telerik BottomSheet
Para implementar o componente Bottom Sheet, é essencial entender que ele consiste em três partes que podemos configurar:
- Conteúdo principal da folha inferior: Container para o conteúdo gráfico que ficará visível antes da exibição da Folha Inferior.
- Conteúdo da folha inferior: Conteúdo que preenche a Folha Inferior e que mostraremos como opções ou informações adicionais ao usuário.
- Alça da Folha Inferior: uma dica visual que indica ao usuário que ele pode arrastar a planilha inferior.
Você pode ver a localização de cada uma dessas partes graficamente abaixo:

Agora que temos essas informações, vamos adicionar uma Folha Inferior ao projeto.
Adicionando o componente BottomSheet a um projeto .NET MAUI
Quando estivermos familiarizados com as partes principais do controle Folha Inferior, a próxima etapa é migrar o conteúdo da UI existente para o controle Folha Inferior. Conteúdo principal da folha inferior seção, usando o Content propriedade da seguinte forma:
<telerik:RadBottomSheet x:Name="AddressBottomSheet">
<telerik:RadBottomSheet.Content>
<Grid>
...
Grid>
telerik:RadBottomSheet.Content>
telerik:RadBottomSheet>
O acima determinará o conteúdo sobre o qual a Folha Inferior aparecerá. A seguir, precisamos especificar o BottomSheetContent tag, onde definiremos o conteúdo que será mostrado ao usuário quando a Folha Inferior aparecer:
<telerik:RadBottomSheet x:Name="AddressBottomSheet">
...
<telerik:RadBottomSheet.BottomSheetContent>
<Grid
Padding="20,20,20,60"
RowDefinitions="Auto,Auto,*,Auto"
RowSpacing="15">
<Grid ColumnDefinitions="*,Auto">
<VerticalStackLayout>
<Label
FontAttributes="Bold"
FontSize="22"
Text="📍 Delivery Address"
TextColor="#333333" />
<Label
Margin="0,5,0,0"
FontSize="13"
Text="Select or add a new delivery address"
TextColor="#888888" />
VerticalStackLayout>
<telerik:RadTemplatedButton
Grid.Column="1"
BackgroundColor="Transparent"
Clicked="OnCloseBottomSheet"
Content="✕"
CornerRadius="20"
FontSize="20"
HeightRequest="40"
TextColor="#666666"
WidthRequest="40" />
Grid>
<telerik:RadBorder
Grid.Row="1"
Padding="12"
BackgroundColor="#EAEAEA"
CornerRadius="12">
<Grid ColumnDefinitions="Auto,*">
<Label
Margin="0,0,10,0"
FontSize="16"
Text="🔍"
VerticalOptions="Center" />
<telerik:RadEntry
x:Name="AddressSearchEntry"
Grid.Column="1"
BackgroundColor="Transparent"
Placeholder="Search your addresses..."
PlaceholderColor="#999999"
BorderThickness="0"
ClearButtonVisibility="WhileEditing"
TextChanged="OnAddressSearchTextChanged" />
Grid>
telerik:RadBorder>
<telerik:RadCollectionView
x:Name="AddressesCollectionView"
Grid.Row="2"
SelectionChanged="OnAddressSelectionChanged"
SelectionMode="Single">
<telerik:RadCollectionView.ItemsLayout>
<telerik:CollectionViewLinearLayout ItemSpacing="10" />
telerik:RadCollectionView.ItemsLayout>
<telerik:RadCollectionView.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource AddressItemStyle}">
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="12">
<VerticalStackLayout Spacing="2" VerticalOptions="Center">
<Label
FontAttributes="Bold"
FontSize="15"
Text="{Binding Label}"
TextColor="#333333" />
<Label
FontSize="13"
LineBreakMode="TailTruncation"
Text="{Binding FullAddress}"
TextColor="#888888" />
VerticalStackLayout>
<Border
Grid.Column="1"
BackgroundColor="{Binding SelectionColor}"
HeightRequest="24"
Stroke="{Binding SelectionBorderColor}"
StrokeShape="RoundRectangle 12"
StrokeThickness="2"
VerticalOptions="Center"
WidthRequest="24">
<Label
FontSize="14"
HorizontalOptions="Center"
Text="{Binding CheckMark}"
TextColor="White"
VerticalOptions="Center" />
Border>
Grid>
Border>
DataTemplate>
telerik:RadCollectionView.ItemTemplate>
telerik:RadCollectionView>
<VerticalStackLayout Grid.Row="3" Spacing="12">
<telerik:RadButton
x:Name="SelectAddressButton"
BackgroundColor="#FB7647"
Clicked="OnSelectAddressClicked"
CornerRadius="12"
FontAttributes="Bold"
HeightRequest="54"
IsEnabled="False"
Text="Select Address"
TextColor="White" />
<telerik:RadButton
BackgroundColor="#4F3F9B"
Clicked="OnAddNewAddressClicked"
CornerRadius="12"
FontAttributes="Bold"
HeightRequest="54"
Text="Add new address"
TextColor="White" />
VerticalStackLayout>
Grid>
telerik:RadBottomSheet.BottomSheetContent>
telerik:RadBottomSheet>
Com o código acima, preparamos o conteúdo da Folha Inferior para ser exibido ao usuário quando o indicarmos.
Mostrando o BottomSheet ao usuário
Assim que tivermos o conteúdo da Folha Inferior pronto, o próximo passo é exibi-lo.
Existem várias maneiras de conseguir isso; usaremos o método GoToBottomSheetStateque permite a transição para um estado específico. Um estado refere-se a quanto espaço de tela a Folha Inferior ocupará, com valores possíveis sendo Hidden (padrão), Minimal (25%), Partial (50%) e Full (90%). Também é possível criar estados personalizados.
Sabendo o que foi dito acima, no meu exemplo usarei o TapGestureRecognizerque faz parte do contêiner que exibe o endereço atual, para mostrar a Folha Inferior a partir daí:
private void OnAddressTapped(object sender, EventArgs e)
{
AddressBottomSheet.GoToBottomSheetState(BottomSheetState.FullState);
}
Da mesma forma que a Folha Inferior pode ser mostrada à vontade, ela também pode ser ocultada usando o mesmo método, GoToBottomSheetState:
private void OnCloseBottomSheet(object sender, EventArgs e)
{
AddressBottomSheet.GoToBottomSheetState(BottomSheetState.HiddenState);
}
A execução das alterações acima resulta no seguinte:

Na imagem acima você pode ver como é possível selecionar um endereço diferente graças ao uso da Folha Inferior, com um visual espetacular, tudo sem sair da janela atual.
Personalizando a folha inferior
O controle Telerik BottomSheet para .NET MAUI oferece diversas propriedades que permitem a personalização do controle. Por exemplo, a propriedade Width permite especificar o espaço horizontal que a Folha Inferior irá ocupar, seja através de um valor absoluto ou de uma porcentagem:

Da mesma forma, se quiser evitar que o usuário arraste para cima ou para baixo no identificador BottomSheet, você pode configurar a propriedade IsSwipeEnabled com um valor false.
Além disso, também é possível modificar a animação da Folha Inferior, habilitando-a ou desabilitando-a com a propriedade IsAnimationEnablede ajustando a duração da animação e a função de atenuação usada por meio das propriedades AnimationDuration e AnimationEasing.
Você também pode alterar recursos como borda, raio do canto e cor de fundo da Folha Inferior através da propriedade BottomSheetContentStyle. Além disso, você pode modificar as propriedades do BottomSheet Handle usando a propriedade HandleStyle.
Abaixo, mostro um exemplo das propriedades mencionadas acima aplicadas à Folha Inferior:
<ContentPage...>
<ContentPage.Resources>
<Style x:Key="BottomSheetContentStyle" TargetType="telerik:BottomSheetContentView">
"BackgroundColor" Value="#F7F7F7" />
"CornerRadius" Value="25,25,0,0" />
"BorderColor" Value="#4F3F9B" />
"BorderThickness" Value="5" />
Style>
<Style x:Key="HandleStyle" TargetType="telerik:BottomSheetHandle">
"BackgroundColor" Value="#4F3F9B" />
"HeightRequest" Value="5" />
"WidthRequest" Value="60" />
"CornerRadius" Value="3" />
Style>
...
ContentPage.Resources>
<telerik:RadBottomSheet
x:Name="AddressBottomSheet"
AnimationDuration="300"
AnimationEasing="{x:Static Easing.CubicOut}"
BottomSheetContentStyle="{StaticResource BottomSheetContentStyle}"
BottomSheetContentWidth="100%"
HandleStyle="{StaticResource HandleStyle}"
IsAnimationEnabled="True"
IsSwipeEnabled="True"
State="Hidden"
StateChanging="OnBottomSheetStateChanging">
...
telerik:RadBottomSheet>
ContentPage>
O resultado da execução com as alterações anteriores aplicadas proporciona maior customização da Folha Inferior:

Com isso, conseguimos uma melhoria visual que centraliza melhor o usuário no conteúdo da Folha Inferior.
Conclusão
Ao longo deste artigo, você aprendeu sobre o componente BottomSheet do conjunto de controle Telerik UI for .NET MAUI, entendendo sua finalidade e como personalizá-lo para mostrar aos usuários opções adicionais sem sair da tela atual.
Sem dúvida, adicionar este tipo de componente às suas aplicações pode melhorar a experiência do usuário, permitindo-lhe realizar ações rápidas ou obter informações com facilidade.
Quer experimentar você mesmo? Telerik UI para Blazor vem com uma avaliação gratuita de 30 dias.




