没有自定义渲染器是不可能的。除了在 iOS 中,该行为在那里按预期工作。但是,这目前不适用于 Windows Phone。
这是我编写的示例课程。只需将一些内容传递给包含换行符的文本属性。我会推荐来自http://i-tools.org/lorem 的东西,只输出纯文本,每行 1 个句子,每段 1 行,如果你不知道怎么想,每行都以 '\n' 结尾。
public class BothDirectionsScrollPage : ContentPage
{
public BothDirectionsScrollPage(string title, string text)
{
this.Title = title;
var count = 0;
var splittext = text.Split('\n');
var stack = new StackLayout();
foreach (var line in splittext)
{
var label = new Label
{
Font = Font.SystemFontOfSize(NamedSize.Medium),
LineBreakMode = LineBreakMode.NoWrap,
FormattedText = new FormattedString()
{
Spans = {new Span {Text = line}}
}
};
stack.Children.Add(label);
count++;
}
var scroll = new ScrollView
{
Padding = 0,
WidthRequest = 500,
Content = stack,
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Orientation = ScrollOrientation.Horizontal
};
Content = new ScrollView()
{
Content = scroll,
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Orientation = ScrollOrientation.Vertical,
};
}
}
这是您需要包含在您的 Android 项目中的自定义渲染器。
using System;
using Android.Views;
using Your.Namespace.Droid.Renderers
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ScrollView), typeof(CustomScrollViewRenderer))]
namespace Your.Namespace.Droid.Renderers
{
/// <summary>
/// Used to allow horizontal and vertical scroll views. Xamarin.Android does not bubble the events down correctly.
/// </summary>
public class CustomScrollViewRenderer : ScrollViewRenderer
{
private float StartX, StartY;
private int IsHorizontal = -1;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (((ScrollView) e.NewElement).Orientation == ScrollOrientation.Horizontal) IsHorizontal = 1;
}
public override bool DispatchTouchEvent(MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
StartX = e.RawX;
StartY = e.RawY;
this.Parent.RequestDisallowInterceptTouchEvent(true);
break;
case MotionEventActions.Move:
if (IsHorizontal*Math.Abs(StartX - e.RawX) < IsHorizontal*Math.Abs(StartY - e.RawY))
this.Parent.RequestDisallowInterceptTouchEvent(false);
break;
case MotionEventActions.Up:
this.Parent.RequestDisallowInterceptTouchEvent(false);
break;
}
return base.DispatchTouchEvent(e);
}
}
}
感谢 Xavyer,http://forums.xamarin.com/discussion/20834/horizontal-scrollview-within-vertical-scrollview