答案 0 :(得分:1)
我尝试在ScrollView
周围放置一个ListView
,但是如果ListView
负责垂直滚动而ScrollView
进行水平滚动,这会导致令人不快的行为。因此,您必须确保ListView
不会在任何方向上滚动,而ScrollView
不会在两个方向上滚动。
只需设置即可轻松实现后者:
scrollView.Orientation = ScrollOrientation.Both;
防止ListView
滚动更加棘手。显然,唯一的方法是确保ListView.HeightRequest
大于实际需要。我最终这样做是这样的:
listView.HeightRequest = listView.RowHeight * (ListUsedAsItemSource.Count + 1) + 1;
方括号内的+ 1
也要为标头设置一些高度。如果没有标题,则可以省略。另外请注意,您将必须手动设置listView.RowHeight
(我认为默认值为40)。就我而言,如果不自行设置,则为-1。
由于ListView
不会水平滚动,因此您无需在此处进行任何阻止。但默认情况下,ListView
将适合水平空间。因此,您还必须将WidthRequest
设置为类似于上面的HeightRequest
。无论如何,您将无法从ListView
获得类似列宽的内容,因此您将自己定义一个值(并将该值用作列的WidthRequest
)
答案 1 :(得分:0)
您可以使用RecyclerView。我已在github上传了一个演示。
您可以下载并测试它。该项目使用RecyclerView
包装另一个RecyclerView
。
答案 2 :(得分:0)
你可以实现横向&自定义控件的垂直列表视图。请参阅此代码,
1)为已渲染的Listview扩展Scrollview属性
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;
namespace ProjectName.CustomControls
{
public class HorizontalListview : ScrollView
{
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(HorizontalListview), default(IEnumerable));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly BindableProperty ItemTemplateProperty =
BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(HorizontalListview), default(DataTemplate));
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public event EventHandler<ItemTappedEventArgs> ItemSelected;
public static readonly BindableProperty SelectedCommandProperty =
BindableProperty.Create("SelectedCommand", typeof(ICommand), typeof(HorizontalListview), null);
public ICommand SelectedCommand
{
get { return (ICommand)GetValue(SelectedCommandProperty); }
set { SetValue(SelectedCommandProperty, value); }
}
public static readonly BindableProperty SelectedCommandParameterProperty =
BindableProperty.Create("SelectedCommandParameter", typeof(object), typeof(HorizontalListview), null);
public object SelectedCommandParameter
{
get { return GetValue(SelectedCommandParameterProperty); }
set { SetValue(SelectedCommandParameterProperty, value); }
}
public void Render()
{
if (ItemTemplate == null || ItemsSource == null)
return;
var layout = new StackLayout();
layout.Spacing = 0;
layout.Orientation = Orientation == ScrollOrientation.Vertical ? StackOrientation.Vertical : StackOrientation.Horizontal;
foreach (var item in ItemsSource)
{
var command = SelectedCommand ?? new Command((obj) =>
{
var args = new ItemTappedEventArgs(ItemsSource, item);
ItemSelected?.Invoke(this, args);
});
var commandParameter = SelectedCommandParameter ?? item;
var viewCell = ItemTemplate.CreateContent() as ViewCell;
viewCell.View.BindingContext = item;
viewCell.View.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = command,
CommandParameter = commandParameter,
NumberOfTapsRequired = 1
});
layout.Children.Add(viewCell.View);
}
Content = layout;
}
}
2)在XAML页面中包含命名空间
xmlns:control="clr-namespace:ProjectName"
3)在您的设计中使用控件
<control:HorizontalListview Orientation="Horizontal" x:Name="lst">
<control:HorizontalListview.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Style="{StaticResource lblPlaceNumberRing}" />
</ViewCell>
</DataTemplate>
</control:HorizontalListview.ItemTemplate>
</control:HorizontalListview>
4)制作适用于Android的渲染器
using System;
using System.ComponentModel;
using ProjectName;
using ProjectName.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(HorizontalListview), typeof(HorizontalListviewRendererAndroid))]
namespace ProjectName.Droid.Renderers
{
public class HorizontalListviewRendererAndroid : ScrollViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
var element = e.NewElement as HorizontalListview;
element?.Render();
if (e.OldElement != null)
e.OldElement.PropertyChanged -= OnElementPropertyChanged;
e.NewElement.PropertyChanged += OnElementPropertyChanged;
}
protected void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (ChildCount > 0)
{
GetChildAt(0).HorizontalScrollBarEnabled = false;
GetChildAt(0).VerticalScrollBarEnabled = false;
}
}
}
}
5)制作适用于iOS的渲染器
using System;
using UIKit;
using ProjectName.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using ProjectName;
using System.ComponentModel;
[assembly: ExportRenderer(typeof(HorizontalListview), typeof(HorizontalListviewRendererIos))]
namespace ProjectName.iOS.Renderers
{
public class HorizontalListviewRendererIos : ScrollViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
var element = e.NewElement as HorizontalListview;
element?.Render();
if (e.OldElement != null)
e.OldElement.PropertyChanged -= OnElementPropertyChanged;
e.NewElement.PropertyChanged += OnElementPropertyChanged;
}
protected void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.ShowsHorizontalScrollIndicator = false;
this.ShowsVerticalScrollIndicator = false;
this.AlwaysBounceHorizontal = false;
this.AlwaysBounceVertical = false;
this.Bounces = false;
}
}
}