如何在 Xamarin.Forms 中获取/检测屏幕大小?
Posted
技术标签:
【中文标题】如何在 Xamarin.Forms 中获取/检测屏幕大小?【英文标题】:How to get/detect screen size in Xamarin.Forms? 【发布时间】:2014-08-19 08:55:24 【问题描述】:我正在尝试重写我为 ios 编写的应用程序。我打算编写一个 android 版本,但认为最好让这个机会使用 Xamarin.Forms。一次做一页,现在我被困在需要获取屏幕宽度和高度的页面上。有谁知道 Xamarin.Forms 中相当于 iOS 的 View.Frame.Width?
【问题讨论】:
【参考方案1】:更新:您可以将Xamarin.Essentials nuget 包用于此目的和许多其他目的。
var width = DeviceDisplay.MainDisplayInfo.Width;
var height = DeviceDisplay.MainDisplayInfo.Height;
旧答案:
有一种简单的方法可以在Xamarin.Forms
中获取屏幕的宽度和高度,并从应用程序的任何位置全局访问它。我会做这样的事情:
1.在您的 App.cs 中创建两个公共成员:
public static class App
public static int ScreenWidth;
public static int ScreenHeight;
...
2。在您的 MainActivity.cs
(Android) 或您的 AppDelegate.cs
(iOS) 中设置值:
安卓:
protected override void OnCreate(Bundle bundle)
...
App.ScreenWidth = (int)Resources.DisplayMetrics.WidthPixels; // real pixels
App.ScreenHeight = (int)Resources.DisplayMetrics.HeightPixels; // real pixels
// App.ScreenWidth = (int)(Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density); // device independent pixels
// App.ScreenHeight = (int)(Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density); // device independent pixels
...
iOS:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
...
App.ScreenWidth = (int)UIScreen.MainScreen.Bounds.Width;
App.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
...
【讨论】:
@Julien 在 Xamarin.Forms 版本 1.3.x 之前是这样。我们在xforms-kickstarter.com 上的参考屏幕尺寸一书中描述了一种更准确的方法。 在 Android 上我建议使用: var pixel = Resources.DisplayMetrics.WidthPixels; // 倾斜像素 var scale = Resources.DisplayMetrics.Density; int dps = (int)((pixels - 0.5f) / scale); App.ScreenWidth = dps;像素 = Resources.DisplayMetrics.HeightPixels; // 下降像素 dps = (int)((pixels - 0.5f) / scale); App.ScreenHeight = dps; // 下降像素【参考方案2】:如果您使用的是 xamarin 表单,那么您可以在可移植类库 (pcl) 中找到当前屏幕的宽度和高度,如下所示。
对于宽度,你在 pcl 中使用它,
Application.Current.MainPage.Width
对于高度,您可以在 pcl 中执行此操作,
Application.Current.MainPage.Height
【讨论】:
我收到运行时异常“对象引用未设置为对象的实例。”。 这会给你定义的宽度和高度。不是实际的屏幕设备尺寸。您可以添加 xaml width=5000,它会返回 5000。您必须使用原生才能获得实际的屏幕尺寸。【参考方案3】:目前没有来自 Xamarin.Forms 本身的方法,但我们已将其实现为 Xamarin.Forms.Labs 中的 PCL 兼容接口,您可以从 NuGet 或来自 GitHub 的源代码获得。
https://github.com/XForms/Xamarin-Forms-Labs
IDevice 具有带有信息的 IDisplay 属性; X 和 Y 的高度、宽度、像素密度以及一些以英寸为单位计算尺寸的扩展方法。
从设备获取信息的示例页面:
https://github.com/XForms/Xamarin-Forms-Labs/blob/master/samples/Xamarin.Forms.Labs.Sample/Pages/Services/ExtendedDeviceInfoPage.cs
#region Display information
var display = device.Display;
var displayFrame = new Frame();
if (display != null)
displayFrame.Content = new StackLayout()
Children =
new Label() Text = display.ToString() ,
new Label() Text = string.Format("Screen width is\t 0:0.0 inches.", display.ScreenWidthInches()) ,
new Label() Text = string.Format("Screen height is\t 0:0.0 inches.", display.ScreenHeightInches()) ,
new Label() Text = string.Format("Screen diagonal size is\t 0:0.0 inches.", display.ScreenSizeInches())
;
else
displayFrame.Content = new Label() TextColor = Color.Red, Text = "Device does not contain display information." ;
stack.Children.Add(displayFrame);
#endregion
无论显示属性如何,都可以在所有平台上创建精确的逐英寸帧:
https://github.com/XForms/Xamarin-Forms-Labs/blob/master/samples/Xamarin.Forms.Labs.Sample/Pages/Services/AbsoluteLayoutWithDisplayInfoPage.cs
public class AbsoluteLayoutWithDisplayInfoPage : ContentPage
public AbsoluteLayoutWithDisplayInfoPage(IDisplay display)
this.Title = "Absolute Layout With Display Info";
var abs = new AbsoluteLayout();
var inchX = display.WidthRequestInInches(1);
var inchY = display.HeightRequestInInches(1);
var originX = display.WidthRequestInInches(display.ScreenWidthInches() / 2);
var originY = display.HeightRequestInInches(display.ScreenHeightInches() / 2);
abs.Children.Add(new Label() Text = "1\"x\"1\" blue frame" );
abs.Children.Add(new Frame()
BackgroundColor = Color.Navy,
,
new Rectangle(originX - inchX/2, originY - inchY/2, inchX, inchY));
abs.Children.Add(new Frame()
BackgroundColor = Color.White
,
new Rectangle(originX - inchX/16, originY - inchY/16, inchX/8, inchY/8));
this.Content = abs;
要获取设备信息,请设置您的 DI 解析器或使用静态容器。所有 3 个平台都有一个带有静态 CurrentDevice 属性的单例设备调用:
resolverContainer.Register<IDevice>(t => WindowsPhoneDevice.CurrentDevice)
resolverContainer.Register<IDevice>(t => AppleDevice.CurrentDevice)
resolverContainer.Register<IDevice>(t => AndroidDevice.CurrentDevice)
【讨论】:
感谢@SKall,我没有以 PCL 方式开发我的应用程序 - 但我一定会看看我是否能得到一些想法。谢谢! 无论是使用共享代码还是 PCL,代码都可以正常工作。在不需要 DI 的共享代码上,只需使用编译器标志来获取当前设备。 谢谢@SKall,明天早上试试。 嗨@SKall,我今天早上终于试过了,但遇到了一些奇怪的事情。 display.ScreenWidthInches() 在 iphone 上总是返回 640,这没有意义,因为我知道宽度应该只超过 300。我想要做的是适合手机框架内的 4 个按钮(它应该是按钮的宽度 =屏幕宽度 / 4)。我错过了什么吗?想法? 你能告诉我PhoneType是什么(Phone.Version)吗?如果是 iPhone,那么 IDevice 在运行时应该是 Phone 类型。您也可以调用 AppleDevice.GetSystemProperty("hw.machine"); 的静态方法;获取硬件版本字符串。这会告诉我识别设备是否有问题。【参考方案4】:食谱
创建一个名为 ScreenSize 的新 Xamarin.Android 应用程序。 编辑 Main.axml 使其包含两个 TextView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_>
<TextView
android:text="Screen Width:"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_
android:layout_
android:id="@+id/screenWidthDp" />
<TextView
android:text="Screen Height:"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_
android:layout_
android:id="@+id/screenHeightDp" />
</LinearLayout>
编辑Activity1.cs,将OnCreate中的代码改成如下:
![在此处输入图片描述][1] 私有 int ConvertPixelsToDp(float pixelValue) var dp = (int) ((pixelValue)/Resources.DisplayMetrics.Density); 返回DP;
运行应用程序。根据设备,它将显示屏幕高度和宽度。以下屏幕截图来自 Galaxy Nexus:
[图片链接]http://i.stack.imgur.com/TQhba.png
【讨论】:
【参考方案5】:在您的 App 文件中定义一个公共静态变量
public static Size ScreenSize;
您应该在调用 App 构造函数之前在 IOS 和 Android 中初始化变量。对于IOS,在FinishedLaunching方法中
App.ScreenSize = new Size(UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
对于 Android,在 OnCreate 函数中
App.ScreenSize = new Xamarin.Forms.Size((int)(Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density), (int)(Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density));
【讨论】:
【参考方案6】:为未来尝试执行此操作但尚未查看或错过的开发人员更新。 Page 类继承自 VisualElement,它现在有两个属性(恰好可以绑定以在 XAML 中使用):
Width - 获取此元素的当前渲染宽度。这是一个只读的可绑定属性。 Height - 获取此元素的当前渲染高度。这是一个只读的可绑定属性。
在您的页面代码隐藏中,您只需执行以下操作:
var myWidth = this.Width;
var myHeight = this.Height;
如果您需要知道它是否发生变化,请使用 SizeChanged 事件:
public MyPage()
SizeChanged += OnSizeChanged;
private void OnSizeChanged(object sender, EventArgs e)
var myWidth = this.Width;
var myHeight = this.Height;
ref: Microsoft Docs
【讨论】:
以上是关于如何在 Xamarin.Forms 中获取/检测屏幕大小?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Xamarin Forms 中获取设备的 GPS 位置?
如何在 Xamarin.Forms.Map 中获取当前位置或移动到当前位置
Xamarin.Forms如何获取当前登录用户的Id等信息?