2

我正在尝试使用此处详述的 XLabs 方法确定屏幕何时旋转(在 Android 中)如何在 Xamarin Forms 中处理屏幕旋转/方向?我遇到了麻烦。

我覆盖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

并且它不会自动设置(当我检查它的使用位置时,它总是设置为“无”),所以我想知道如何使用它,实际上,如何使用 XLabs/IXFormsApp 来确定回转?

在相关的说明中,我还尝试设置 Rotation 处理程序(不知道为什么,但我想我会试一试),结果不寻常。

            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 代码(使用结果的地方)中设置它,那很好(尽管处理程序似乎从未真正被调用过)。有谁知道为什么会这样?

4

2 回答 2

1

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


第一种方法是创建一个 PageBase 类,我的所有页面都从该类继承,而 PageBase 则从常规 Page 继承。

我的 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; }
  }
}

就个人而言,我更喜欢以第二种方式编写它并使其检查“如果我们处于肖像模式,这里有区别”。这样那些在肖像和风景之间没有区别的东西只需要写一次,只需要写两次不同的地方。

于 2015-09-20T22:29:17.400 回答
0

您可以使用 OnSizeAllocated 方法覆盖来检测方向变化;

double previousWidth;
double previousHeight;

    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);

        if (previousWidth != width || previousHeight != height)
        {
            previousWidth = width;
            previousHeight = height;

            if (width > height)
            {
                // landscape mode
            }
            else
            {
                // portrait mode
            }   
        }
    }
于 2015-09-20T19:15:23.913 回答