37

有什么方法可以ListView用类似horizontal scrollXamarin.Forms图像创建

列表视图水平

这就是我为垂直所做的

var myListView = new ListView
{
    ItemTemplate = new DataTemplate(typeof(ImageCell))
};
4

14 回答 14

16

从 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>
于 2016-05-16T00:16:49.853 回答
12

是的,你在技术上可以。将 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>
于 2014-06-20T21:29:50.970 回答
11

正如其他人所说,不 - Xamarin.Forms中没有现成可用的。

但是 - 它不会阻止任何人编写自己的自定义渲染器来实现这种类型的控制。

正如Stephane Delcroix所提到的,您可以创建一个ScrollView,然后创建一个StackLayout作为子级来创建相同的效果。

然后,您将需要实施:-

*)可绑定属性以接受需要创建的 ( IEnumerable ) ItemsSource属性。

*)可绑定属性以接受需要创建的 ( DataTemplate ) ItemTemplate属性。

*)绑定代码以实例化ItemTemplate的实例,该实例采用特定的数据源项并将其呈现到StackLayout中。您还必须考虑删除的项目等。

*) 为项目选择附加事件处理程序/点击手势。

*) 实现选定状态/停用其他选定项目。

...等等以获得完整的实施。

上述所有问题的问题在于,它适用于相对较小的项目列表。

但是,如果您正在寻找一长串条目,那么由于您正在预先创建所有视图,因此上述内容可能有点不受欢迎。

即使您延迟加载这些,您仍然需要考虑所有视图的内存占用

然后这会导致另一个可能的实现来处理Virtualized Items,这是一个完全不同的故事。

于 2014-08-28T20:19:20.760 回答
10

如上所述,没有标准的方法可以做到这一点,但是有一种使用标准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 中供每个人使用。

于 2015-03-18T14:04:24.127 回答
9

在 Xamarin.Forms 4.0-pre 中,您可以使用CollectionView,它简化了获取这种类型的布局。

样本:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <ListItemsLayout>
            <x:Arguments>
                <ItemsLayoutOrientation>Horizontal</ItemsLayoutOrientation>    
            </x:Arguments>
        </ListItemsLayout>
    </CollectionView.ItemsLayout>
</CollectionView>
于 2019-01-15T21:16:11.633 回答
7

就像其他人所说的那样,ListView 不可能,我认为 Xamarin 对 Forms 的疏忽很大。我们需要动态显示数据驱动的对象,而不仅仅是一个列表……加油!

但是,在 Xamarin Labs 项目中,您可以使用 GridView。它仍然有点粗糙,人们现在正在通过选择项目来解决一些错误。

https://github.com/XForms/Xamarin-Forms-Labs

有人似乎确实有解决这个问题的方法:

https://github.com/XForms/Xamarin-Forms-Labs/issues/236

于 2014-08-28T13:06:48.703 回答
6

不,没有办法有一个水平的ListView. 您可以将水平 StackLayout 包装在水平 ScrollView 中以实现相同的视觉效果,但这并不完全相同,因为您不会有 DataTemplating。

于 2014-06-20T18:22:33.553 回答
3

我没有尝试过,但这可能值得一试。

https://github.com/Cheesebaron/Cheesebaron.Horizo​​ntalListView

于 2014-08-23T15:55:26.453 回答
3

这个 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>

我希望它有帮助:)

于 2018-05-27T17:52:37.940 回答
2

我已经尝试过提到的“旋转”解决方案,除了它是一个“丑陋”的解决方案之外,它还存在一些限制

  1. 列表视图 WidthRequest 必须与 HeightRequest 相同
  2. listView 行高不再正常工作,因为它变成了单元格宽度
  3. 垂直对齐变成了水平对齐等,不是很容易维护。

更好的选择是制作自己的自定义控件,或者像我一样使用现有的 Horizo​​ntalListViewhttps ://www.nuget.org/packages/Horizo​​ntalListView1.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>
于 2016-12-07T11:05:53.390 回答
1

CollectionView出来之前,您可以使用我的 Xamarin.Forms Horizo ​​ntalListView

它有:

  • 捕捉第一个或中间元素
  • 填充和项目间距
  • 处理 NotifyCollectionChangedAction 添加、删除和重置操作
  • 查看回收
  • Android 上的 RecyclerView
  • iOS 上的 UICollectionView
  • 实际上,这种实现在理念和实现方面与提供未来 Xamarin CollectionView 的内容非常接近。
于 2018-10-15T08:25:01.390 回答
0

据我所知,有3种方法可以实现:

  1. 旋转(正如其他人所提到的
    • 无需再做标准的 ListView
    • 项目模板可用
    • 丑陋的解决方案!
  2. 自定义渲染(Android 中的 RecyclerView 和(我认为)iOS 中的 UICollectionView
    • 自定义单元格可用(我确定 Android,但不确定 iOS)
    • 需要更多的工作和代码
  3. Grid 和 Horizo​​ntal ScrollView(在 ScrollView 中使用水平作为方向属性的值
    • 自定义布局可用
    • 此解决方案中没有可用的 CachingStrategy,因此对于庞大的列表,这可能会导致您的应用使用大量 RAM
于 2018-04-10T04:31:44.503 回答
0

这个怎么样:https ://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/layout#horizo​​ntal-list

在 XAML 中,CollectionView 可以通过将其 ItemsLayout 属性设置为 Horizo​​ntalList 来在水平列表中显示其项目:

<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 对象来完成此布局,将 Horizo​​ntal ItemsLayoutOrientation 枚举成员指定为 Orientation 属性值:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Horizontal" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>
于 2020-09-29T13:54:55.920 回答
-1

这已通过一个名为 ItemsView 的自定义类解决(不要与 Xamarin 的 ItemsView 混淆,用于在 ListView 中进行数据模板化),它实现了上面提到的 ScrollView/StackPanel 模式,该示例已被请求。请看代码:https ://gist.github.com/fonix232/b88412a976f67315f915

于 2016-03-26T11:32:19.937 回答