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

Cell外观

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

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平台都允许单击按钮,而不实现自定义渲染器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值