如何在 Xamarin Forms 中处理屏幕 rotation/orientation?

How to handle screen rotation/orientation in Xamarin Forms?

在 Xamarin Forms 中是否有针对不同视图和平台(Android、iOS、WinPhone)处理 rotation/orientation 的(半)通用方法?

UI 会旋转,这已经足够好了,尽管它会破坏我的布局(现在是绝对布局)。我想使用 Stacklayout 我可以使它更灵活一点,但是当布局更复杂时会在其他地方遇到障碍。

我能否使用相同的 ViewModel 以某种方式显示纵向和横向的不同视图? (我正在使用基于 XLAB 的 MVVM。)

我找到的可能解决方案:

http://blog.rthand.com/post/2014/07/24/Different-XAML-layouts-for-different-device-orienations-in-XamarinForms.aspx 缺少 iOS,我想知道它是否能很好地处理 MVVM,不过看起来不错,我现在正在调查它

http://www.jimbobbennett.io/orientation-with-xamarin-forms/ 听起来很有希望,但样本只有 iOS,链接的 GIT 存储库根本没有文档,它只是说 "Xamarin Helpers"

http://www.sellsbrothers.com/posts/Details/13740 也可能用于以编程方式创建的视图。尽管在我的测试中,旋转时 ios 模拟器没有收到 size changed 事件(尽管我在不同的代码位置收听)。 (解决方法是根据size changed检测旋转。)

如果您已经在使用 XLabs,那么您可以使用 IXFormsApp 和 属性 'Orientation' 和事件处理程序 'Rotation'。您必须为每个平台添加本机观察器并在那里设置 IXFormsApp 的 'Orientation',这将导致事件处理程序调用。

例如 iOS:

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        var xapp = new XFormsAppiOS();
        xapp.Init(this);

        var resolverContainer = new SimpleContainer();
        resolverContainer.Register<IXFormsApp>(xapp);
        Resolver.SetResolver(resolverContainer.GetResolver());

        var a = new App();
        LoadApplication(a);

        UIDevice.Notifications.ObserveOrientationDidChange((s, e) =>
        {
            xapp.Orientation = ... // set orientation here
        });

现在您可以通过解析 IXFormsApp 来监控方向变化:

        xapp = Resolver.Resolve<IXFormsApp>();
        if (xapp.Orientation == Orientation.Landscape) { ... } else { ... } 
        xapp.Rotation += (sender, args) =>
        {
            switch (args.Value)
            {
                case Orientation.LandscapeLeft:
                    break;
                default:
                    // etc.
                    break;
            }
        };

至于布局,我想 RelativeLayout 将是最方便的选择,因为您可以将方向放在 Constraint 的内部。旋转时使布局自行刷新。