How to get DPI device to PCL in Xamarin. Forms?

2020-07-30 06:31发布

问题:

I need to get DPI device in my Xamarin class PCL. I do not want to use Xamarin.Essentials. Can I do this using Native interfaces, if its possible, how can I do it?

回答1:

in your pcl create a new interface called IDisplayInfo:

public interface IDisplayInfo
{
    int GetDisplayWidth();
    int GetDisplayHeight();
    int GetDisplayDpi();
}

In your android implementation, add a new class:

[assembly: Dependency(typeof(DisplayInfo))]
namespace YourAppNamespace.Droid
{
    public class DisplayInfo : IDisplayInfo
    {
        public int GetDisplayWidth()
        {
            return (int)Android.App.Application.Context.Resources.DisplayMetrics.WidthPixels;
        }

        public int GetDisplayHeight()
        {
            return (int)Android.App.Application.Context.Resources.DisplayMetrics.HeightPixels;
        }

        public int GetDisplayDpi()
        {
            return (int)Android.App.Application.Context.Resources.DisplayMetrics.DensityDpi;
        }
    }
}

and in the iOS implementation, add the same class:

[assembly: Dependency(typeof(DisplayInfo))] 
namespace YourNamespace.iOS
{
    public class DisplayInfo : IDisplayInfo
    {
        public int GetDisplayWidth()
        {
            return (int)UIScreen.MainScreen.Bounds.Width;
        }

        public int GetDisplayHeight()
        {
            return (int)UIScreen.MainScreen.Bounds.Height;
        }

        public int GetDisplayDpi()
        {
            return (int)(int)UIScreen.MainScreen.Scale;
        }
    }
}

Now in your shared code, you can call

int dpi = DependencyService.Get<IDisplayInfo>().GetDisplayDpi();

and should be good to go. Note that i also added methods for getting screen width and height, basically because i already had them in my code and since you are probably going to need them sooner or later anyways.



回答2:

I have a static class Core to store some shared stuff defined the shared code. On app start it's receiving values for later use everywhere:

Android MainActivity OnCreate:

    Core.IsAndroid = true;
    Core.DisplayDensity = Resources.DisplayMetrics.Density;

iOS AppDelegate FinishedLaunching:

        Core.IsIOS = true;
        Core.DisplayDensity = (float)(UIScreen.MainScreen.NativeBounds.Width / UIScreen.MainScreen.Bounds.Width);


回答3:

Currently Device Display Information available via official Xamarin.Essentials nuget package, see: https://docs.microsoft.com/en-us/xamarin/essentials/device-display

// Get Metrics
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;

// Orientation (Landscape, Portrait, Square, Unknown)
var orientation = mainDisplayInfo.Orientation;

// Rotation (0, 90, 180, 270)
var rotation = mainDisplayInfo.Rotation;

// Width (in pixels)
var width = mainDisplayInfo.Width;

// Height (in pixels)
var height = mainDisplayInfo.Height;

// Screen density
var density = mainDisplayInfo.Density;