有什么方法可以ListView
用类似horizontal scroll
的Xamarin.Forms
图像创建
这就是我为垂直所做的
var myListView = new ListView
{
ItemTemplate = new DataTemplate(typeof(ImageCell))
};
有什么方法可以ListView
用类似horizontal scroll
的Xamarin.Forms
图像创建
这就是我为垂直所做的
var myListView = new ListView
{
ItemTemplate = new DataTemplate(typeof(ImageCell))
};
从 Xamarin Forms 2.3CarouselView
开始,就可以做到这一点,甚至更多。在这里阅读更多。
<ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<CarouselView ItemsSource="{Binding MyDataSource}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding LabelText}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ContentView>
是的,你在技术上可以。将 Rotation 设置为 270(所有 VisualElements 都有一个 Rotation BindableProperty)。然而,这看起来像是一个次优的解决方案,因为顶部和底部都有空白,您必须左右拖动视图才能完全看到所有内容。
public static readonly BindableProperty RotationProperty;
public static readonly BindableProperty RotationXProperty;
public static readonly BindableProperty RotationYProperty;
上面的代码来自 VisualElement 类。下面的代码是我自己的一个小示例。
∨∨∨
<ListView x:Name="MessagesListView" Rotation="270" ItemsSource="{Binding Items}" RowHeight="40">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<!--mylayouthere-->
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
正如其他人所说,不 - Xamarin.Forms中没有现成可用的。
但是 - 它不会阻止任何人编写自己的自定义渲染器来实现这种类型的控制。
正如Stephane Delcroix所提到的,您可以创建一个ScrollView,然后创建一个StackLayout作为子级来创建相同的效果。
然后,您将需要实施:-
*)可绑定属性以接受需要创建的 ( IEnumerable ) ItemsSource属性。
*)可绑定属性以接受需要创建的 ( DataTemplate ) ItemTemplate属性。
*)绑定代码以实例化ItemTemplate的实例,该实例采用特定的数据源项并将其呈现到StackLayout中。您还必须考虑删除的项目等。
*) 为项目选择附加事件处理程序/点击手势。
*) 实现选定状态/停用其他选定项目。
...等等以获得完整的实施。
上述所有问题的问题在于,它适用于相对较小的项目列表。
但是,如果您正在寻找一长串条目,那么由于您正在预先创建所有视图,因此上述内容可能有点不受欢迎。
即使您延迟加载这些,您仍然需要考虑所有视图的内存占用。
然后这会导致另一个可能的实现来处理Virtualized Items,这是一个完全不同的故事。
如上所述,没有标准的方法可以做到这一点,但是有一种使用标准ListView
和@MillieSmiths 方法的方法。
该解决方案需要多层嵌套布局。从 ListView 开始,我们将旋转 270 度,但这也会旋转我们的项目内容,因此我们需要将其旋转 90 度。
旋转 ListView 会产生大量空白,通过将 ListView 包装在绝对布局中,我们可以解决这个问题(我们需要一个额外的 contentview 来解决一些剪切问题)。
最后在代码隐藏中,我们需要渲染布局剪辑
看完整的解决方案:
<AbsoluteLayout x:Name="MessagesLayoutFrame" Padding="0" HorizontalOptions="FillAndExpand">
<ContentView x:Name="MessagesLayoutFrameInner" Padding="0" HorizontalOptions="FillAndExpand">
<ListView x:Name="MessagesListView"
ItemsSource="{Binding Images}"
RowHeight="240"
VerticalOptions="Start"
HeightRequest="240"
WidthRequest="240"
SeparatorVisibility="None"
Rotation="270"
HorizontalOptions="Center">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView Rotation="90" Padding="12">
<Image Source="{Binding Source}" Aspect="AspectFill" />
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentView>
</AbsoluteLayout>
对于后面的代码,我们只需要检查我们之前是否设置过,如果有,就放手。基本上我们正在找出页面的宽度是多少(NameGrid
只是其他地方的全宽容器)然后将直接 ListView 容器向上移动一半的空白,并将其裁剪到底部的另一半)
bool hasAppearedOnce = false;
protected override void OnAppearing() {
base.OnAppearing();
if (!hasAppearedOnce) {
hasAppearedOnce = true;
var padding = (NameGrid.Width - MessagesListView.Height) / 2;
MessagesListView.HeightRequest = MessagesLayoutFrame.Width;
MessagesLayoutFrameInner.WidthRequest = MessagesLayoutFrame.Width;
MessagesLayoutFrameInner.Padding = new Thickness(0);
MessagesLayoutFrame.Padding = new Thickness(0);
MessagesLayoutFrame.IsClippedToBounds = true;
Xamarin.Forms.AbsoluteLayout.SetLayoutBounds(MessagesLayoutFrameInner, new Rectangle(0, 0 - padding, AbsoluteLayout.AutoSize, MessagesListView.Height - padding));
MessagesLayoutFrameInner.IsClippedToBounds = true;
// */
}
}
警告
请勿<FRAMES>
用于布局移动和旋转。它会在 Windows Phone 上崩溃。
PS 我相信这可以包含在一个不错的 UserControl 中供每个人使用。
在 Xamarin.Forms 4.0-pre 中,您可以使用CollectionView,它简化了获取这种类型的布局。
样本:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<ListItemsLayout>
<x:Arguments>
<ItemsLayoutOrientation>Horizontal</ItemsLayoutOrientation>
</x:Arguments>
</ListItemsLayout>
</CollectionView.ItemsLayout>
</CollectionView>
就像其他人所说的那样,ListView 不可能,我认为 Xamarin 对 Forms 的疏忽很大。我们需要动态显示数据驱动的对象,而不仅仅是一个列表……加油!
但是,在 Xamarin Labs 项目中,您可以使用 GridView。它仍然有点粗糙,人们现在正在通过选择项目来解决一些错误。
https://github.com/XForms/Xamarin-Forms-Labs
有人似乎确实有解决这个问题的方法:
不,没有办法有一个水平的ListView
. 您可以将水平 StackLayout 包装在水平 ScrollView 中以实现相同的视觉效果,但这并不完全相同,因为您不会有 DataTemplating。
我没有尝试过,但这可能值得一试。
https://github.com/Cheesebaron/Cheesebaron.HorizontalListView
这个 nuget 包将非常适合您的情况。我以前用过这个,我真的很喜欢它:
https://github.com/SuavePirate/DynamicStackLayout
为了让事情变得更好,请下载这 3 个 Nuget 包,以便对您的照片进行图像加载、缓存和转换。照片将呈圆形,但此 nuget 具有其他类型的转换:
Xamarin.FFImageLoading (https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-API)
Xamarin.FFImageLoading.Forms
Xamarin.FFImageLoading.Transformations (https://github.com/luberda-molinet/FFImageLoading/wiki/Transformations-Guide)
这里有一段代码可以帮助你开始:
<!--Add this code to the top of your page-->
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
xmlns:dynamicStackLayout="clr-namespace:SuaveControls.DynamicStackLayout;assembly=SuaveControls.DynamicStackLayout"
<!-- Here is your control inside a ScrollView. The property Photos is a list of images address (Urls) -->
<ScrollView Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<dynamicStackLayout:DynamicStackLayout ItemsSource="{Binding Photos}" HorizontalOptions="Fill" Orientation="Horizontal" Padding="10, -0, 100, 10">
<dynamicStackLayout:DynamicStackLayout.ItemTemplate>
<DataTemplate>
<StackLayout BackgroundColor="Transparent" >
<ffimageloading:CachedImage HorizontalOptions="Start" VerticalOptions="Center" DownsampleToViewSize="true" Aspect="AspectFit" Source="{Binding .}">
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=PhotoCommand}" CommandParameter="{Binding .}" NumberOfTapsRequired="1" />
</ffimageloading:CachedImage.GestureRecognizers>
<ffimageloading:CachedImage.HeightRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="50" />
<On Platform="Android" Value="60" />
</OnPlatform>
</ffimageloading:CachedImage.HeightRequest>
<ffimageloading:CachedImage.WidthRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="50" />
<On Platform="Android" Value="60" />
</OnPlatform>
</ffimageloading:CachedImage.WidthRequest>
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation BorderHexColor="#eeeeee">
<fftransformations:CircleTransformation.BorderSize>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="10" />
<On Platform="Android" Value="10" />
</OnPlatform>
</fftransformations:CircleTransformation.BorderSize>
</fftransformations:CircleTransformation>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
</StackLayout>
</DataTemplate>
</dynamicStackLayout:DynamicStackLayout.ItemTemplate>
</dynamicStackLayout:DynamicStackLayout>
</ScrollView>
我希望它有帮助:)
我已经尝试过提到的“旋转”解决方案,除了它是一个“丑陋”的解决方案之外,它还存在一些限制:
更好的选择是制作自己的自定义控件,或者像我一样使用现有的 HorizontalListView:https ://www.nuget.org/packages/HorizontalListView1.1/这个很容易使用。你可以在这里找到源代码和文档
执行:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="test.ListPage"
xmlns:Controls="clr-namespace:HorizontalList;assembly=HorizontalList">
<Controls:HorizontalListView ItemsSource="{Binding Categories}" ListOrientation="Horizontal">
<Controls:HorizontalListView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name}" />
</DataTemplate>
</Controls:HorizontalListView.ItemTemplate>
</Controls:HorizontalListView>
</ContentPage>
在CollectionView出来之前,您可以使用我的 Xamarin.Forms Horizo ntalListView。
它有:
据我所知,有3种方法可以实现:
在 XAML 中,CollectionView 可以通过将其 ItemsLayout 属性设置为 HorizontalList 来在水平列表中显示其项目:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
或者,也可以通过将 ItemsLayout 属性设置为 LinearItemsLayout 对象来完成此布局,将 Horizontal ItemsLayoutOrientation 枚举成员指定为 Orientation 属性值:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
这已通过一个名为 ItemsView 的自定义类解决(不要与 Xamarin 的 ItemsView 混淆,用于在 ListView 中进行数据模板化),它实现了上面提到的 ScrollView/StackPanel 模式,该示例已被请求。请看代码:https ://gist.github.com/fonix232/b88412a976f67315f915