我正在尝试使用这里详细介绍的XLabs方法来确定屏幕何时旋转(在Android中),How to handle screen rotation/orientation in Xamarin Forms?和我遇到了问题。
我重写了OnConfigurationChanged方法在MainActivity中
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文档将其列为“受保护的集”,编译器也是如此:
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'但是,如果我在表单代码(使用结果的地方)中设置了它,那么它就很好了(尽管处理程序似乎从未真正被调用过)。有人知道这是怎么回事吗?
发布于 2015-09-20 22:29:17
我过去使用过两种不同的解决方案。
第一种方法是创建一个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; }
}
}就我个人而言,我更喜欢用第二种方式编写它,并让它检查“如果我们处于portait模式,这里有不同之处”。这样,那些在门户和景观之间没有区别的东西,只需要写一次,只写两次。
发布于 2015-09-20 19:15:23
您可以使用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
}
}
}https://stackoverflow.com/questions/32642732
复制相似问题