如何在 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 实现页面全屏显示

如何在 Xamarin Forms 中获取设备的 GPS 位置?

如何在 Xamarin.Forms.Map 中获取当前位置或移动到当前位置

Xamarin.Forms如何获取当前登录用户的Id等信息?

xamarin/xamarin.forms 在锁屏电源唤醒时保持后台运行

Xamarin.Forms (UWP) - 如何获取 WebView 的 DOM 作为 HTML 字符串?