ListView 外观
除了自定义列表中每行的 ViewCell
实例之外,Xamarin.FormsListView
还允许你自定义列表的呈现方式。
分组
以连续滚动列表形式呈现时,大量数据可能会变得难以处理。 在这些情况下,启用分组可以通过更好地组织内容和激活特定于平台的控件来使数据导航变得更加容易,从而改善用户体验。
为 ListView
激活分组时,将为每个组添加一个标题行。
若要启用分组功能,请执行以下操作:
- 创建列表列表(组列表,每个组都是元素列表)。
- 将
ListView
的ItemsSource
设置为该列表。 - 将
IsGroupingEnabled
设置为 true。 - 将
GroupDisplayBinding
设置为绑定到用作组标题的组属性。 - [可选] 将
GroupShortNameBinding
设置为绑定到用作组的短名称的组属性。 短名称用于跳转列表(iOS 上的右侧列)。
首先为组创建类:
public class PageTypeGroup : List<PageModel>
{
public string Title { get; set; }
public string ShortName { get; set; } //will be used for jump lists
public string Subtitle { get; set; }
private PageTypeGroup(string title, string shortName)
{
Title = title;
ShortName = shortName;
}
public static IList<PageTypeGroup> All { private set; get; }
}
在上面的代码中,All
是将作为绑定源提供给 ListView 的列表。 Title
和 ShortName
是将用于组标题的属性。
在此阶段,All
是一个空列表。 添加静态构造函数,以便在程序启动时填充列表:
static PageTypeGroup()
{
List<PageTypeGroup> Groups = new List<PageTypeGroup> {
new PageTypeGroup ("Alpha", "A"){
new PageModel("Amelia", "Cedar", new switchCellPage(),""),
new PageModel("Alfie", "Spruce", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Ava", "Pine", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Archie", "Maple", new switchCellPage(), "grapefruit.jpg")
},
new PageTypeGroup ("Bravo", "B"){
new PageModel("Brooke", "Lumia", new switchCellPage(),""),
new PageModel("Bobby", "Xperia", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Bella", "Desire", new switchCellPage(), "grapefruit.jpg"),
new PageModel("Ben", "Chocolate", new switchCellPage(), "grapefruit.jpg")
}
};
All = Groups; //set the publicly accessible list
}
在上面的代码中,我们还可以对 Groups
的元素调用 Add
,这些元素是类型 PageTypeGroup
的实例。 此方法之所以可行,是因为 PageTypeGroup
继承自 List<PageModel>
。
下面是用于显示已分组列表的 XAML:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DemoListView.GroupingViewPage"
<ContentPage.Content>
<ListView x:Name="GroupedView"
GroupDisplayBinding="{Binding Title}"
GroupShortNameBinding="{Binding ShortName}"
IsGroupingEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"
Detail="{Binding Subtitle}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
该 XAML 执行下列操作:
- 将
GroupShortNameBinding
设置为我们的组类中定义的ShortName
属性 - 将
GroupDisplayBinding
设置为我们的组类中定义的Title
属性 - 将
IsGroupingEnabled
设置为 true - 将
ListView
的ItemsSource
更改为已分组列表
以下屏幕截图显示生成的 UI:
自定义分组
如果列表中已启用分组,则还可以自定义组标头。
与 ListView
有一个用于定义行显示方式的 ItemTemplate
类似,ListView
有一个 GroupHeaderTemplate
。
此处显示了在 XAML 中自定义组标头的示例:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DemoListView.GroupingViewPage">
<ContentPage.Content>
<ListView x:Name="GroupedView"
GroupDisplayBinding="{Binding Title}"
GroupShortNameBinding="{Binding ShortName}"
IsGroupingEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"
Detail="{Binding Subtitle}"
TextColor="#f35e20"
DetailColor="#503026" />
</DataTemplate>
</ListView.ItemTemplate>
<!-- Group Header Customization-->
<ListView.GroupHeaderTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"
Detail="{Binding ShortName}"
TextColor="#f35e20"
DetailColor="#503026" />
</DataTemplate>
</ListView.GroupHeaderTemplate>
<!-- End Group Header Customization -->
</ListView>
</ContentPage.Content>
</ContentPage>
页眉和页脚
ListView 可以呈现随列表元素滚动的页眉和页脚。 页眉和页脚可以是文本字符串或更复杂的布局。 此行为与分区组不同。
可以将 Header
和/或 Footer
设置为 string
值,也可以将它们设置为更复杂的布局。 还有 HeaderTemplate
和 FooterTemplate
属性,可让你为支持数据绑定的页眉和页脚创建更复杂的布局。
若要创建基本的页眉/页脚,只需将“页眉”或“页脚”属性设置为要显示的文本即可。 在代码中:
ListView HeaderList = new ListView()
{
Header = "Header",
Footer = "Footer"
};
在 XAML 中:
<ListView x:Name="HeaderList"
Header="Header"
Footer="Footer">
...
</ListView>
若要创建自定义页眉和页脚,请定义“页眉”和“页脚”视图:
<ListView.Header>
<StackLayout Orientation="Horizontal">
<Label Text="Header"
TextColor="Olive"
BackgroundColor="Red" />
</StackLayout>
</ListView.Header>
<ListView.Footer>
<StackLayout Orientation="Horizontal">
<Label Text="Footer"
TextColor="Gray"
BackgroundColor="Blue" />
</StackLayout>
</ListView.Footer>
滚动条可见性
ListView
类具有 HorizontalScrollBarVisibility
和 VerticalScrollBarVisibility
属性,这些属性获取或设置一个 ScrollBarVisibility
值,该值表示水平或垂直滚动条何时可见。 这两个属性都可以设置为以下值:
Default
指示平台的默认滚动条行为,并且是HorizontalScrollBarVisibility
和VerticalScrollBarVisibility
属性的默认值。Always
指示滚动条将可见,即使内容大小适合视图。Never
指示滚动条将不可见,即使内容大小不适合视图。
行分隔符
在 iOS 和 Android 上,默认情况下,分隔线显示在 ListView
元素之间。 如果你希望在 iOS 和 Android 上隐藏分隔线,请在 ListView 上设置 SeparatorVisibility
属性。 SeparatorVisibility
的选项包括:
- Default - 在 iOS 和 Android 上显示分隔线。
- None - 在所有平台上隐藏分隔符。
默认可见性:
C#:
SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.Default;
XAML:
<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="Default" />
无:
C#:
SeparatorDemoListView.SeparatorVisibility = SeparatorVisibility.None;
XAML:
<ListView x:Name="SeparatorDemoListView" SeparatorVisibility="None" />
还可以通过 SeparatorColor
属性设置分隔线的颜色:
C#:
SeparatorDemoListView.SeparatorColor = Color.Green;
XAML:
<ListView x:Name="SeparatorDemoListView" SeparatorColor="Green" />
注意
加载 ListView
后在 Android 上设置这些属性中的任何一个都会导致很大的性能损失。
行高
默认情况下,ListView 中的所有行都具有相同的高度。 ListView 有两个可用于更改该行为的属性:
HasUnevenRows
–true
/false
值,如果设置为true
,则行具有不同的高度。 默认为false
。RowHeight
– 当HasUnevenRows
为false
时设置每行的高度。
可以通过设置 ListView
上的 RowHeight
属性来设置所有行的高度。
自定义固定行高度
C#:
RowHeightDemoListView.RowHeight = 100;
XAML:
<ListView x:Name="RowHeightDemoListView" RowHeight="100" />
不均匀行
如果希望各行有不同的高度,可以将 HasUnevenRows
属性设置为 true
。 将 HasUnevenRows
设置为 true
后,无需手动设置行高,因为高度将由 Xamarin.Forms 自动计算。
C#:
RowHeightDemoListView.HasUnevenRows = true;
XAML:
<ListView x:Name="RowHeightDemoListView" HasUnevenRows="true" />
在运行时重设行大小
如果 HasUnevenRows
属性设置为 true
,则可在运行时以编程方式重设各个 ListView
行的大小。 Cell.ForceUpdateSize
方法会更新单元格的大小,即使单元格当前不可见,如以下代码示例所示:
void OnImageTapped (object sender, EventArgs args)
{
var image = sender as Image;
var viewCell = image.Parent.Parent as ViewCell;
if (image.HeightRequest < 250) {
image.HeightRequest = image.Height + 100;
viewCell.ForceUpdateSize ();
}
}
OnImageTapped
事件处理程序的执行是为了响应单元格中的 Image
被点击的操作,该处理程序会增加单元格中显示的 Image
的大小,使之便于查看。
警告
过度使用运行时行重设大小可能会导致性能下降。