是否可以在 ListView
中创建horizontal scroll
Xamarin.Forms
,如图片
这是我为垂直
所做的var myListView = new ListView
{
ItemTemplate = new DataTemplate(typeof(ImageCell))
};
答案 0 :(得分:11)
是的,你在技术上可以。将“旋转”设置为270(所有VisualElements都具有“旋转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>
答案 1 :(得分:10)
正如其他人所说的那样,不 - Xamarin.Forms 中没有开箱即用的。
然而 - 它并没有阻止任何人编写自己的自定义渲染器来实现这种控制。
正如 Stephane Delcroix 所提到的,你可以创建一个 ScrollView ,然后创建一个 StackLayout 来创建相同的效果。
然后您需要实施: -
*)可绑定属性以接受需要创建的( IEnumerable ) ItemsSource 属性。
*) bindable property 以接受需要创建的( DataTemplate ) ItemTemplate 属性。
*)绑定代码,用于实例化 ItemTemplate 的实例,获取特定数据源项并将其呈现为 StackLayout 。您还必须考虑删除的项目等。
*)附加事件处理程序/点击手势以选择项目。
*)实施选定状态/停用其他所选项目。
......等等,以获得完整的实施。
以上所有问题都是对于相对较小的项目清单来说很好。
但是,如果您要查找很长的条目列表,那么在您创建所有视图之前,上面会有点不受欢迎。
即使你延迟加载,你仍然需要考虑所有视图的内存占用。
然后引入另一个可能的实施,处理虚拟物品,这是一个完全不同的故事。
答案 2 :(得分:10)
如上所述,没有标准的方法可以做到这一点,但是有一种方法可以使用标准ListView
和@MillieSmiths方法。
该解决方案需要多层嵌套布局。从ListViewwe开始将旋转270度,但是也会旋转我们的项目内容,因此我们需要将其向后旋转90度。
旋转ListView创建了大量的空白,通过将ListView包装在绝对布局中我们可以解决这个问题(我们需要额外的内容视图来修复一些剪辑问题)。
最后在代码隐藏中我们需要渲染布局剪辑
看到完整的解决方案:
<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上崩溃。
P.S 我相信这可以包含在一个很好的UserControl中,供所有人使用。
答案 3 :(得分:8)
从Xamarin Forms 2.3开始CarouselView
就是这样,等等。阅读更多here。
<ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<CarouselView ItemsSource="{Binding MyDataSource}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding LabelText}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ContentView>
答案 4 :(得分:7)
就像其他人所说的那样,ListView不可能,我认为Xamarin对Forms有很大的疏忽。我们需要动态显示数据驱动对象,而不仅仅是列表中的内容....来吧你好!
但是,在Xamarin Labs项目中,您可以使用GridView。它仍然有点粗糙,人们正在通过选择项目来解决一些错误。
https://github.com/XForms/Xamarin-Forms-Labs
似乎某人似乎有解决这个问题的方法:
答案 5 :(得分:6)
不,没有办法让水平ListView
。您可以将水平StackLayout包装在水平ScrollView中以获得相同的视觉效果,但这并不完全相同,因为您没有DataTemplating。
答案 6 :(得分:3)
答案 7 :(得分:2)
我已经尝试了上面提到的&#34;旋转&#34;解决方案,除了它是一个丑陋的&#34;解决方案,它还带有几个限制:
更好的选择是制作自己的自定义控件,或者像我一样,使用现有的HorizontalListView :https://www.nuget.org/packages/HorizontalListView1.1/这个很容易使用。您可以找到源代码和文档here
实现:
<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>
答案 8 :(得分:2)
这款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>
我希望它有所帮助:)
答案 9 :(得分:1)
在Xamarin.Forms 4.0-pre中,您可以使用CollectionView,从而简化了这种布局的设计。
示例:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<ListItemsLayout>
<x:Arguments>
<ItemsLayoutOrientation>Horizontal</ItemsLayoutOrientation>
</x:Arguments>
</ListItemsLayout>
</CollectionView.ItemsLayout>
</CollectionView>
答案 10 :(得分:0)
据我所知,有三种方法可以实现这一点:
答案 11 :(得分:0)
直到CollectionView用完为止,您可以使用我的Xamarin.Forms HorizontalListView。
它具有:
答案 12 :(得分:0)
在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>
答案 13 :(得分:-1)
这已经通过一个名为ItemsView的自定义类(不要与XViewrin的ListView中的ListView中的数据模板混淆)来解决,它实现了上面提到的ScrollView / StackPanel模式,该模型已经被请求了。请参阅代码:https://gist.github.com/fonix232/b88412a976f67315f915