首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在XLabs.XLabs/XLabs中处理屏幕旋转/定位?

如何在XLabs.XLabs/XLabs中处理屏幕旋转/定位?
EN

Stack Overflow用户
提问于 2015-09-18 02:05:35
回答 2查看 1.6K关注 0票数 2

我正在尝试使用这里详细介绍的XLabs方法来确定屏幕何时旋转(在Android中),How to handle screen rotation/orientation in Xamarin Forms?和我遇到了问题。

我重写了OnConfigurationChanged方法在MainActivity

代码语言:javascript
复制
        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中的定向变量,即xapp.Orientation,我遇到了问题。XLabs文档将其列为“受保护的集”,编译器也是如此:

代码语言:javascript
复制
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来确定旋转?

另外,我还试图设置旋转处理程序(不确定原因,但我想我会尝试一下),结果不寻常。

代码语言:javascript
复制
            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代码,就会得到以下错误:

代码语言:javascript
复制
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'

但是,如果我在表单代码(使用结果的地方)中设置了它,那么它就很好了(尽管处理程序似乎从未真正被调用过)。有人知道这是怎么回事吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-20 22:29:17

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

第一种方法是创建一个PageBase类,我的所有页面都是从它继承的,而PageBase则是从普通页面继承的。

我的PageBase有两个抽象方法(因此它的子方法必须填充它),它们是UpdateLandscape和UpdatePortait。孩子们将填写这些方法,以便如何布局页面,这取决于页面是以景观模式还是以肖像模式布局。

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

如果,正如您所说的,您只是想检查它何时旋转,上面的工作很好,因为当您旋转您的手机时,OnSizeAllocated会被调用一个页面。

如果您希望您的代码能够在任何时候进行检查,那么下面的第二个解决方案也是有效的。

第二种解决方法是使用依赖关系服务来填充IDeviceInfo接口,并通过检查DeviceInfo.IsPortait()是否为真或假来编写所有动态事物(这种方式还让DeviceInfo有一个宽度和高度,这样我就可以随时请求屏幕尺寸)。

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

代码语言:javascript
复制
[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中,我给出了以下方法:

代码语言:javascript
复制
public int GetWidth() {
      return (int)(Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density);
    }

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

在iOS方面,我填写了如下内容:

代码语言:javascript
复制
[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; }
  }
}

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

票数 1
EN

Stack Overflow用户

发布于 2015-09-20 19:15:23

您可以使用OnSizeAllocated方法覆盖检测方向更改;

代码语言:javascript
复制
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
            }   
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32642732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档