如何处理Xamarin.Forms / XLabs中的屏幕旋转/方向?

时间:2015-09-18 02:05:36

标签: android xamarin xamarin.forms screen-orientation xlabs

我正在尝试使用此处详细说明的How to handle screen rotation/orientation in Xamarin Forms?确定屏幕旋转(在Android中)并且我遇到了麻烦。

我覆盖 MainActivity

中的 OnConfigurationChanged 方法
        public override void OnConfigurationChanged (Android.Content.Res.Configuration newConfig)
    {
        base.OnConfigurationChanged (newConfig);

        var xapp = Resolver.Resolve<IXFormsApp> ();
        if (xapp == null)
            return;

        switch (newConfig.Orientation) {
        case Android.Content.Res.Orientation.Landscape:
            xapp.Orientation = XLabs.Enums.Orientation.Landscape;
            break;
        case Android.Content.Res.Orientation.Portrait:
            //xapp.Orientation = XLabs.Enums.Orientation.Portrait;
            break;
        default:
            break;
        }
        }

我遇到了IXFormsApp中的Orientation变量,即xapp.Orientation。 XLabs文档将此列为“受保护集”,编译器也是如此:

MainActivity.cs(109,5,109,21): error CS0200: Property or indexer 'XLabs.Platform.Mvvm.IXFormsApp.Orientation' cannot be assigned to -- it is read only

并且它没有自动设置(当我检查它的使用位置时,它总是设置为'None'),所以我想知道如何使用它,实际上,如何使用XLabs / IXFormsApp确定轮换?

在一个相关的说明中,我也试图设置旋转处理程序(不知道为什么,但我认为我会试一试),结果不同寻常。

            xapp.Rotation += (sender, args) =>
        {
            switch (args.Value)
            {
            case XLabs.Enums.Orientation.Landscape:
                //xapp.Orientation = XLabs.Enums.Orientation.Landscape;
                ...
                break;
            case XLabs.Enums.Orientation.Portrait:
                ...
                break;
            default:
                break;
            }
            };

如果我尝试Android代码,我会收到以下错误:

MainActivity.cs(60,4,60,22): error CS0019: Operator '+=' cannot be applied to operands of type 'System.EventHandler<XLabs.EventArgs<XLabs.Enums.Orientation>>' and 'lambda expression'

但是,如果我在Forms代码中设置它(使用结果),那就没问题了(尽管实际上看起来似乎没有调用过)。有谁知道会是这样吗?

1 个答案:

答案 0 :(得分:1)

我过去使用过两种不同的解决方案。

第一个是创建一个我的所有页面继承的PageBase类,而PageBase继承自常规页面。

我的PageBase有两个抽象方法(所以它的子节点必须填充它),它们是UpdateLandscape和UpdatePortait。孩子们将填写这些方法,以了解如何布局页面,具体取决于它是以横向还是纵向模式布局。

页面有一个方法OnSizeAllocated,正如丹尼尔所说。我让PageBase覆盖它,并相应地调用UpdateLandscape和UpdatePortait。

如果如你所说的那样,你只是想检查旋转的时间,上面的工作正常,因为只要你转动手机就会调用OnSizeAllocated页面。

如果您正在检查横向与肖像,因为您希望您的代码能够随时检查,那么下面的第二个解决方案也适用。

我解决它的第二种方法是使用依赖服务来填充IDeviceInfo接口,并通过检查DeviceInfo.IsPortait()是真还是假来编写所有动态内容(这样我也让DeviceInfo有宽度和高度,所以我可以在任何时候请求屏幕尺寸。)

在Android上,我填写了我的Android代码:

[assembly: Dependency (typeof(Namespace.DeviceInfoProvider))]
namespace Namespace
{
  public class DeviceInfoProvider : IDeviceInfoProvider
  {
    public bool IsPortait () { return DeviceInfoManager.Width < DeviceInfoManager.Height; }
    public int GetWidth () {  return DeviceInfoManager.Width; }
    public int GetHeight () { return DeviceInfoManager.Height; }
  }

  public static class DeviceInfoManager
  {
    public static MainActivity MainActivity { get; set; }
    public static int Width { get { return MainActivity.GetWidth (); } }
    public static int Height { get { return MainActivity.GetHeight (); } }
  }
}

然后在MainActivity中我给了它们这些方法:

public int GetWidth() {
      return (int)(Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density);
    }

    public int GetHeight() {
      return (int)(Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density);
    }

在iOS方面,我这样填写:

[assembly: Dependency (typeof(Namespace.DeviceInfoProvider))]
namespace Namespace {

  public class DeviceInfoProvider : IDeviceInfoProvider {
    public bool IsPortait() { return UIScreen.MainScreen.Bounds.Width < UIScreen.MainScreen.Bounds.Height; }

    public int GetWidth() { return (int)UIScreen.MainScreen.Bounds.Width; }

    public int GetHeight() { return (int)UIScreen.MainScreen.Bounds.Height; }
  }
}

就个人而言,我更倾向于以第二种方式编写它并进行检查&#34;如果我们处于肖像模式,这里就是差异&#34;。这样那些在肖像和风景之间没有区别的东西只需要写一次,只差异被写两次。