Xamarin.Forms ScrollView
ScrollView
é um layout capaz de rolar seu conteúdo. A ScrollView
classe deriva da Layout
classe e, por padrão, rola seu conteúdo verticalmente. Um ScrollView
só pode ter um único filho, embora isso possa ser outros layouts.
Aviso
Os objetos ScrollView
não devem ser aninhados. Além disso, os objetos ScrollView
não devem ser aninhados com outros controles que fornecem rolagem, como CollectionView
, ListView
e WebView
.
ScrollView
define as propriedades a seguir:
- O
Content
, do tipoView
, representa o conteúdo a ser exibido noScrollView
. - O
ContentSize
, do tipoSize
, representa o tamanho do conteúdo. Trata-se de uma propriedade somente leitura. - O
HorizontalScrollBarVisibility
, do tipoScrollBarVisibility
, representa quando a barra de rolagem horizontal está visível. - O
Orientation
, do tipoScrollOrientation
, representa a direção de rolagem doScrollView
. O valor padrão dessa propriedade éVertical
. - O
ScrollX
, do tipodouble
, indica a posição de rolagem X atual. O valor padrão dessa propriedade somente leitura é 0. - O
ScrollY
, do tipodouble
, indica a posição de rolagem Y atual. O valor padrão dessa propriedade somente leitura é 0. - O
VerticalScrollBarVisibility
, do tipoScrollBarVisibility
, representa quando a barra de rolagem vertical está visível.
Essas propriedades são apoiadas por objetos BindableProperty
, com exceção da propriedade Content
, o que significa que elas podem ser alvos de associações de dados e estilizadas.
A propriedade Content
é o ContentProperty
da classe ScrollView
e, portanto, não precisa ser definida explicitamente no XAML.
Dica
Para obter o melhor desempenho de layout possível, siga as diretrizes em Otimizar o desempenho do layout.
ScrollView como um layout raiz
Um ScrollView
só pode ter um único filho, que pode ser outros layouts. Portanto, é comum que um ScrollView
seja o layout raiz em uma página. Para rolar seu conteúdo filho, o ScrollView
calcula a diferença entre a altura de seu conteúdo e sua própria altura. Essa diferença é a quantidade que o ScrollView
pode rolar seu conteúdo.
Muitas vezes, um StackLayout
será o filho de um ScrollView
. Nesse cenário, o ScrollView
faz com que o StackLayout
tenha a mesma altura que a soma das alturas de seus filhos. Então o ScrollView
consegue determinar a quantidade que seu conteúdo pode ser rolado. Para obter mais informações sobre o StackLayout
, consulte Xamarin.Forms StackLayout.
Cuidado
Em um ScrollView
vertical, evite definir a propriedade VerticalOptions
como Start
, Center
ou End
. Fazer isso indica que o ScrollView
deve ter apenas a altura necessária, o que pode ser zero. Embora Xamarin.Forms proteja contra essa eventualidade, é melhor evitar um código que sugira algo que você não deseja que aconteça.
O exemplo XAML a seguir tem um ScrollView
como layout raiz em uma página:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ScrollViewDemos"
x:Class="ScrollViewDemos.Views.ColorListPage"
Title="ScrollView demo">
<ScrollView>
<StackLayout BindableLayout.ItemsSource="{x:Static local:NamedColor.All}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<BoxView Color="{Binding Color}"
HeightRequest="32"
WidthRequest="32"
VerticalOptions="Center" />
<Label Text="{Binding FriendlyName}"
FontSize="24"
VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</ContentPage>
Neste exemplo, o ScrollView
tem seu conteúdo definido como um StackLayout
que usa um layout vinculável para exibir os Color
campos definidos por Xamarin.Forms. Por padrão, o ScrollView
rola verticalmente, o que revela mais conteúdo:
Este é o código C# equivalente:
public class ColorListPageCode : ContentPage
{
public ColorListPageCode()
{
DataTemplate dataTemplate = new DataTemplate(() =>
{
BoxView boxView = new BoxView
{
HeightRequest = 32,
WidthRequest = 32,
VerticalOptions = LayoutOptions.Center
};
boxView.SetBinding(BoxView.ColorProperty, "Color");
Label label = new Label
{
FontSize = 24,
VerticalOptions = LayoutOptions.Center
};
label.SetBinding(Label.TextProperty, "FriendlyName");
StackLayout horizontalStackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Children = { boxView, label }
};
return horizontalStackLayout;
});
StackLayout stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, NamedColor.All);
BindableLayout.SetItemTemplate(stackLayout, dataTemplate);
ScrollView scrollView = new ScrollView { Content = stackLayout };
Title = "ScrollView demo";
Content = scrollView;
}
}
Para obter mais informações sobre layouts associáveis, consulte Layouts vinculáveis no Xamarin.Forms.
ScrollView como um layout filho
Um ScrollView
pode ser um layout filho de um layout pai diferente.
Muitas vezes, um ScrollView
será o filho de um StackLayout
. Um ScrollView
exige uma altura específica para calcular a diferença entre a altura de seu conteúdo e sua própria altura, e a diferença é a quantidade que ScrollView
pode rolar seu conteúdo. Quando um ScrollView
é filho de um StackLayout
, ele não recebe uma altura específica. O StackLayout
deseja que o ScrollView
seja o mais curto possível, que é a altura do conteúdo do ScrollView
ou zero. Para lidar com esse cenário, a VerticalOptions
ScrollView
propriedade do deve ser definida como FillAndExpand
. Isso fará com que o StackLayout
dê ao ScrollView
o espaço extra que não foi usado pelos outros filhos e, então, o ScrollView
terá uma altura específica.
O exemplo XAML a seguir tem um ScrollView
como o layout filho para um StackLayout
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScrollViewDemos.Views.BlackCatPage"
Title="ScrollView as a child layout demo">
<StackLayout Margin="20">
<Label Text="THE BLACK CAT by Edgar Allan Poe"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="Center" />
<ScrollView VerticalOptions="FillAndExpand">
<StackLayout>
<Label Text="FOR the most wild, yet most homely narrative which I am about to pen, I neither expect nor solicit belief. Mad indeed would I be to expect it, in a case where my very senses reject their own evidence. Yet, mad am I not -- and very surely do I not dream. But to-morrow I die, and to-day I would unburthen my soul. My immediate purpose is to place before the world, plainly, succinctly, and without comment, a series of mere household events. In their consequences, these events have terrified -- have tortured -- have destroyed me. Yet I will not attempt to expound them. To me, they have presented little but Horror -- to many they will seem less terrible than barroques. Hereafter, perhaps, some intellect may be found which will reduce my phantasm to the common-place -- some intellect more calm, more logical, and far less excitable than my own, which will perceive, in the circumstances I detail with awe, nothing more than an ordinary succession of very natural causes and effects." />
<!-- More Label objects go here -->
</StackLayout>
</ScrollView>
</StackLayout>
</ContentPage>
Neste exemplo, há dois StackLayout
objetos. O primeiro StackLayout
é o objeto de layout raiz, que tem um Label
objeto e um ScrollView
como seus filhos. O ScrollView
tem um StackLayout
como seu conteúdo, com o StackLayout
contendo vários objetos Label
. Essa disposição garante que o primeiro Label
esteja sempre na tela, enquanto o texto exibido pelos outros objetos Label
pode ser rolado:
Este é o código C# equivalente:
public class BlackCatPageCS : ContentPage
{
public BlackCatPageCS()
{
Label titleLabel = new Label
{
Text = "THE BLACK CAT by Edgar Allan Poe",
// More properties set here to define the Label appearance
};
ScrollView scrollView = new ScrollView
{
VerticalOptions = LayoutOptions.FillAndExpand,
Content = new StackLayout
{
Children =
{
new Label
{
Text = "FOR the most wild, yet most homely narrative which I am about to pen, I neither expect nor solicit belief. Mad indeed would I be to expect it, in a case where my very senses reject their own evidence. Yet, mad am I not -- and very surely do I not dream. But to-morrow I die, and to-day I would unburthen my soul. My immediate purpose is to place before the world, plainly, succinctly, and without comment, a series of mere household events. In their consequences, these events have terrified -- have tortured -- have destroyed me. Yet I will not attempt to expound them. To me, they have presented little but Horror -- to many they will seem less terrible than barroques. Hereafter, perhaps, some intellect may be found which will reduce my phantasm to the common-place -- some intellect more calm, more logical, and far less excitable than my own, which will perceive, in the circumstances I detail with awe, nothing more than an ordinary succession of very natural causes and effects.",
},
// More Label objects go here
}
}
};
Title = "ScrollView as a child layout demo";
Content = new StackLayout
{
Margin = new Thickness(20),
Children = { titleLabel, scrollView }
};
}
}
Orientação
O ScrollView
tem uma propriedade Orientation
, que representa a direção de rolagem do ScrollView
. Essa propriedade é do tipo ScrollOrientation
, que define os seguintes membros:
- O
Vertical
indica que oScrollView
irá rolar verticalmente. Esse membro é o valor padrão da propriedadeOrientation
. - O
Horizontal
indica que oScrollView
irá rolar horizontalmente. - O
Both
indica que oScrollView
irá rolar horizontal e verticalmente. - O
Neither
indica que oScrollView
não irá rolar.
Dica
A rolagem pode ser desabilitada definindo a propriedade Orientation
como Neither
.
Detectar rolagem
ScrollView
define um Scrolled
evento que é disparado para indicar que a rolagem ocorreu. O objeto ScrolledEventArgs
que acompanha o evento Scrolled
tem as propriedades ScrollX
e ScrollY
, ambas do tipo double
.
Importante
As propriedades ScrolledEventArgs.ScrollX
e ScrolledEventArgs.ScrollY
podem ter valores negativos, devido ao efeito de retorno que ocorre ao rolar de volta para o início de ScrollView
.
O exemplo XAML a seguir mostra um ScrollView
que define um manipulador de eventos para o evento Scrolled
:
<ScrollView Scrolled="OnScrollViewScrolled">
...
</ScrollView>
Este é o código C# equivalente:
ScrollView scrollView = new ScrollView();
scrollView.Scrolled += OnScrollViewScrolled;
Neste exemplo, o manipulador de eventos OnScrollViewScrolled
é executado quando o evento Scrolled
é acionado:
void OnScrollViewScrolled(object sender, ScrolledEventArgs e)
{
Console.WriteLine($"ScrollX: {e.ScrollX}, ScrollY: {e.ScrollY}");
}
Neste exemplo, o manipulador de eventos OnScrollViewScrolled
gera os valores do objeto ScrolledEventArgs
que acompanha o evento.
Observação
O evento Scrolled
é acionado para rolagens iniciadas pelo usuário e para rolagens programáticas.
Rolar programaticamente
O ScrollView
define dois métodos ScrollToAsync
, que rolam de forma assíncrona o ScrollView
. Uma das sobrecargas rola para uma posição especificada no ScrollView
, enquanto a outra rola um elemento especificado para exibição. Ambas as sobrecargas têm um argumento adicional que pode ser usado para indicar se deseja animar a rolagem.
Importante
Os métodos ScrollToAsync
não resultarão em rolagem quando a propriedade ScrollView.Orientation
for definida como Neither
.
Rolar uma posição para a exibição
Uma posição dentro de um ScrollView
pode ser rolada com o método ScrollToAsync
, que aceita os argumentos double
, x
e y
. Dado um objeto vertical ScrollView
chamado scrollView
, o exemplo a seguir mostra como rolar até 150 unidades independentes de dispositivo da parte superior do ScrollView
:
await scrollView.ScrollToAsync(0, 150, true);
O terceiro argumento para o ScrollToAsync
é o argumento animated
, que determina se uma animação de rolagem é exibida ao rolar programaticamente um ScrollView
.
Rolar um elemento para a exibição
Um elemento dentro de um ScrollView
pode ser rolado para a exibição com o método ScrollToAsync
que aceita os argumentos Element
e ScrollToPosition
. Dado um ScrollView
vertical chamado scrollView
e um Label
chamado label
, o exemplo a seguir mostra como rolar um elemento para a exibição:
await scrollView.ScrollToAsync(label, ScrollToPosition.End, true);
O terceiro argumento para o ScrollToAsync
é o argumento animated
, que determina se uma animação de rolagem é exibida ao rolar programaticamente um ScrollView
.
Ao rolar um elemento para a exibição, a posição exata do elemento após terminar a rolagem pode ser definida com o segundo argumento, position
, do método ScrollToAsync
. Esse argumento aceita um membro de enumeração ScrollToPosition
:
MakeVisible
indica que o elemento deve ser rolado até ficar visível noScrollView
.Start
indica que o elemento deve ser rolado até o início doScrollView
.Center
indica que o elemento deve ser rolado até o centro doScrollView
.End
indica que o elemento deve ser rolado até o final doScrollView
.
Visibilidade da barra de rolagem
O ScrollView
define as propriedades HorizontalScrollBarVisibility
e VerticalScrollBarVisibility
, que são apoiadas por propriedades associáveis. Essas propriedades obtêm ou definem um valor de enumeração ScrollBarVisibility
, que representa se a barra de rolagem horizontal ou vertical está visível. A enumeração ScrollBarVisibility
define os seguintes membros:
- O
Default
indica o comportamento da barra de rolagem padrão para a plataforma e é o valor padrão das propriedadesHorizontalScrollBarVisibility
eVerticalScrollBarVisibility
. - O
Always
indica que as barras de rolagem estarão visíveis, mesmo quando o conteúdo se ajustar à exibição. Never
indica que as barras de rolagem não ficarão visíveis, mesmo que o conteúdo não caiba na visualização.