Xamarin.Forms 用户界面——控件——ListView——Cell 外观

来源:互联网 发布:凤凰金融 以大数据为 编辑:程序博客网 时间:2024/06/05 22:32

Cell外观

探索用于呈现数据的选项,同时利用ListView的便利。

PDF用于离线使用
  • 下载PDF
相关样品:
  • 内置单元格
  • 自定义单元格
  • 绑定上下文已更改

让我们知道你对此的感受

最后更新:2016年12月

ListView提供可滚动列表,可以通过使用ViewCells 进行自定义。ViewCells可用于显示文本和图像,指示真/假状态并接收用户输入。

从ListView单元格中可以看到两种方法:

  • 定制内置单元格 - 更容易实现和更好的性能,牺牲可定制性。
  • 创建自定义单元格 - 更多地控制最终结果,但如果不能正确实现,则可能会遇到性能问题。

内置单元格

Xamarin.Forms配有内置单元格,适用于许多简单的应用程序:

  • TextCell - 用于显示文本
  • ImageCell - 用于显示带有文本的图像。

另外两个细胞,SwitchCellEntryCell可用,但它们不是通常与使用ListView。查看TableView有关这些单元格的更多信息。

TextCell

TextCell 是用于显示文本的单元格,可选地具有第二行作为详细文本。

TextCells在运行时呈现为本机控件,因此与自定义相比,性能非常好ViewCell。TextCells是可定制的,允许您设置:

  • Text - 第一行显示的文字,大字体。
  • Detail - 第一行显示的文本,字体较小。
  • TextColor - 文字的颜色。
  • DetailColor - 细节文字的颜色

的ImageCell

ImageCellTextCell可以用于显示文本和二次详细文本,并通过使用每个平台的本机控件提供了很好的性能。ImageCell不同之处TextCell在于它显示文本左侧的图像。

ImageCell当您需要显示具有可视化方面的数据列表(例如联系人或电影列表)时,此功能非常有用。ImageCells是可定制的,允许您设置:

  • Text - 第一行显示的文字,大字体
  • Detail - 第一行显示的文本,字体较小
  • TextColor - 文字的颜色
  • DetailColor - 细节文字的颜色
  • ImageSource - 文本旁边显示的图像

请注意,当定位到Windows Phone 8.1时,ImageCell默认情况下不会缩放图像。另外请注意,默认情况下,Windows Phone 8.1是唯一以与主文本相同的颜色和字体显示细节文本的平台。Windows Phone 8.0呈现ImageCell如下:

自定义单元格

当内置单元格不提供所需的布局时,自定义单元格实现了所需的布局。例如,您可能想要呈现一个具有相同权重的两个标签的单元格。A LabelCell将不够,因为它LabelCell有一个较小的标签。

所有自定义单元格必须从ViewCell所有内置单元格类型使用的相同基类派生。

大多数单元格自定义添加额外的只读数据(如附加标签,图像或其他显示信息)。如果添加了可以聚焦的按钮或其他控件,则在Android上可能无法点击单元本身。见下文,以克服这个限制。

Xamarin.Forms 2 在控件上引入了一个新的缓存行为ListView,可以将其设置为提高某些类型的自定义单元格的滚动性能。

这是一个自定义单元格的示例:

XAML

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.ImageCellPage">    <ContentPage.Content>        <ListView  x:Name="listView">            <ListView.ItemTemplate>                <DataTemplate>                    <ViewCell>                        <StackLayout BackgroundColor="#eee"                        Orientation="Vertical">                            <StackLayout Orientation="Horizontal">                                <Image Source="{Binding image}" />                                <Label Text="{Binding title}"                                TextColor="#f35e20" />                                <Label Text="{Binding subtitle}"                                HorizontalOptions="EndAndExpand"                                TextColor="#503026" />                            </StackLayout>                        </StackLayout>                    </ViewCell>                </DataTemplate>            </ListView.ItemTemplate>        </ListView>    </ContentPage.Content></ContentPage>

上面的XAML正在做很多。我们来吧吧

  • 自定义单元格嵌套在一个DataTemplate内部ListView.ItemTemplate。这是与使用任何其他单元格相同的过程。
  • ViewCell是自定义单元格的类型。DataTemplate元素的子元素必须是或从类型导出的ViewCell
  • 注意在里面ViewCell,布局是由a管理的StackLayout。此布局允许我们自定义背景颜色。请注意,任何StackLayout可绑定的属性可以绑定到自定义单元格内,尽管此处未显示。

C#

在C#中指定一个自定义单元格比XAML等效的更加冗长。让我们来看看:

首先,定义一个自定义单元格类ViewCell作为基类:

public class CustomCell : ViewCell    {        public CustomCell()        {            //instantiate each of our views            var image = new Image ();            StackLayout cellWrapper = new StackLayout ();            StackLayout horizontalLayout = new StackLayout ();            Label left = new Label ();            Label right = new Label ();            //set bindings            left.SetBinding (Label.TextProperty, "title");            right.SetBinding (Label.TextProperty, "subtitle");            image.SetBinding (Image.SourceProperty, "image");            //Set properties for desired design            cellWrapper.BackgroundColor = Color.FromHex ("#eee");            horizontalLayout.Orientation = StackOrientation.Horizontal;            right.HorizontalOptions = LayoutOptions.EndAndExpand;            left.TextColor = Color.FromHex ("#f35e20");            right.TextColor = Color.FromHex ("503026");            //add views to the view hierarchy            horizontalLayout.Children.Add (image);            horizontalLayout.Children.Add (left);            horizontalLayout.Children.Add (right);            cellWrapper.Children.Add (horizontalLayout);            View = cellWrapper;        }    }

在您的页面的构造函数中ListView,将ListView的ItemTemplate属性设置为新的DataTemplate

public partial class ImageCellPage : ContentPage    {        public ImageCellPage ()        {            InitializeComponent ();            listView.ItemTemplate = new DataTemplate (typeof(CustomCell));        }    }

请注意,构造函数DataTemplate需要一个类型。typeof运算符获取CLR类型CustomCell

绑定上下文更改

当绑定到自定义单元格类型的BindableProperty实例时,显示BindableProperty值的UI控件应该使用OnBindingContextChangedoverride来设置要在每个单元格中显示的数据,而不是单元格构造函数,如下面的代码示例所示:

public class CustomCell : ViewCell{    Label nameLabel, ageLabel, locationLabel;    public static readonly BindableProperty NameProperty =        BindableProperty.Create ("Name", typeof(string), typeof(CustomCell), "Name");    public static readonly BindableProperty AgeProperty =        BindableProperty.Create ("Age", typeof(int), typeof(CustomCell), 0);    public static readonly BindableProperty LocationProperty =        BindableProperty.Create ("Location", typeof(string), typeof(CustomCell), "Location");    public string Name {        get { return(string)GetValue (NameProperty); }        set { SetValue (NameProperty, value); }    }    public int Age {        get { return(int)GetValue (AgeProperty); }        set { SetValue (AgeProperty, value); }    }    public string Location {        get { return(string)GetValue (LocationProperty); }        set { SetValue (LocationProperty, value); }    }    ...    protected override void OnBindingContextChanged ()    {        base.OnBindingContextChanged ();        if (BindingContext != null) {            nameLabel.Text = Name;            ageLabel.Text = Age.ToString ();            locationLabel.Text = Location;        }    }}

OnBindingContextChanged倍率将被称为当BindingContextChanged事件触发,响应的价值BindingContext特性改变。因此,当BindingContext更改时,显示BindableProperty值的UI控件应设置其数据。请注意,BindingContext应该检查一个null值,因为这可以由Xamarin.Forms设置为垃圾回收,这反过来将导致OnBindingContextChanged覆盖被调用。

或者,UI控件可以绑定到BindableProperty实例以显示其值,从而无需覆盖该OnBindingContextChanged方法。

当覆盖时OnBindingContextChanged,请确保OnBindingContextChanged调用基类的方法,以便注册的代理接收BindingContextChanged事件。

在XAML中,可以将自定义单元格类型绑定到数据,如下面的代码示例所示:

<ListView x:Name="listView">    <ListView.ItemTemplate>        <DataTemplate>            <local:CustomCell Name="{Binding Name}" Age="{Binding Age}" Location="{Binding Location}" />        </DataTemplate>    </ListView.ItemTemplate></ListView>

此结合NameAgeLocation可绑定属性在CustomCell比如,对NameAgeLocation底层集合中的每个对象的属性。

C#中的等效绑定如下代码示例所示:

var customCell = new DataTemplate (typeof(CustomCell));customCell.SetBinding (CustomCell.NameProperty, "Name");customCell.SetBinding (CustomCell.AgeProperty, "Age");customCell.SetBinding (CustomCell.LocationProperty, "Location");var listView = new ListView {    ItemsSource = people,    ItemTemplate = customCell};

在iOS和Android上,如果ListView是循环元素,并且自定义单元格使用自定义渲染器,则自定义渲染器必须正确实现属性更改通知。当重新使用单元格时,当绑定上下文更新为可用单元格的属性值时,其属性值将更改,并PropertyChanged引发事件。有关详细信息,请参阅自定义ViewCell。有关细胞再循环的更多信息,请参阅缓存策略。

在Android上启用行选择

为了允许对包含诸如按钮之类的输入元素的单元格进行行选择,需要简单custom renderer。在通用代码中,创建一个子类,Button以便在平台项目中添加自定义渲染器:

public class ListButton : Button { }

Android的渲染器实现只需设置Focusable允许行可选择的属性以及可主机可点击的按钮。此代码已添加到Android应用程序项目中:

[assembly: ExportRenderer (typeof (ListButton), typeof (ListButtonRenderer))]// ...public class ListButtonRenderer : ButtonRenderer {    protected override void OnElementChanged (ElementChangedEventArgs<ListButton> e) {        base.OnElementChanged (e);        Control.Focusable = false;    }}

如上所述,只有Android需要ButtonRenderer实现。iOS和Windows Phone平台都允许单击按钮,而不实现自定义渲染器。

阅读全文
0 0
原创粉丝点击