48

I am creating one Xamarin Forms project and I got stuck in finding the current screen width according to the different device.

I know how it can be done in android and ios but need a way to find the width in portable.

Tushar patel
  • 3,279
  • 3
  • 27
  • 30

7 Answers7

82

You can try this Application.Current.MainPage.Width in my case this worked and i am able to find the device width in portable project itself.

Parth Patel
  • 3,937
  • 2
  • 27
  • 44
  • 3
    That would most probably be equivalent to just typing this.Width directly. Lifecycle timing is relevant here. – frezq Nov 12 '18 at 17:47
  • 1
    This works great, except on initial load when the MainPage hadn't been presented yet. – Meekohi Dec 21 '20 at 20:01
  • 1
    I had this fails on Samsung S20 - Android 11 . because it is initialized as -1 . You should change to @Evs solution now. – Ashi May 06 '21 at 20:15
78

I know it is an old thread but worth mentioning that recently Xamarin.Essentials NuGet pakage was released and there is a useful class DeviceDisplay in there that should handle this task for you.

The documentation can be found here.

Usage example:

// 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;

// Width (in xamarin.forms units)
var xamarinWidth = width / mainDisplayInfo.Density;

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

// Screen density
var density = mainDisplayInfo.Density;
Dolan
  • 313
  • 1
  • 4
  • 14
EvZ
  • 11,889
  • 4
  • 38
  • 76
  • 5
    `DeviceDisplay.ScreenMetrics` seems to have been renamed to `DeviceDisplay.MainDisplayInfo`. – Aaron T Mar 19 '19 at 18:40
  • 16
    I had to divide `mainDisplayInfo.Width/Height` by `mainDisplayInfo.Density` to get the values I was looking for. – user875234 Apr 02 '19 at 17:44
  • dividing the by the density is the correct width. The same result can be achieved by using Application.Current.MainPage.Width; – chri3g91 Jul 29 '20 at 07:26
  • 3
    Good answer, but note this will bite you if you're on a device where the App window size is not the full device width/height (e.g. Chromebook) – Meekohi Dec 21 '20 at 19:48
32

Common code (in App.xaml.cs)

public static int ScreenHeight {get; set;}
public static int ScreenWidth {get; set;}

Android part (in MainActivity.cs, in the OnCreate method)

App.ScreenHeight = (int) (Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density);
App.ScreenWidth = (int) (Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density);

iOS part (in AppDelegate.cs, in the FinishedLaunching method)

App.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
App.ScreenWidth = (int)UIScreen.MainScreen.Bounds.Width;

So App.ScreenHeight and App.ScreenWidth will be initialized when the App will be launched, then you will be able to use them anywhere in the common code.

Dolan
  • 313
  • 1
  • 4
  • 14
Nicolas Bodin
  • 1,431
  • 1
  • 20
  • 25
8

You can use the Width property when you are in a ContentPage. For example,

protected override void OnAppearing()
{
    base.OnAppearing();
    double w = this.Width;
}

Note that this is set during the Layout phase. So, you can only use it after the page is initialized, otherwise it is -1.

https://developer.xamarin.com/api/property/Xamarin.Forms.VisualElement.Width/

Khoa Tran
  • 121
  • 1
  • 9
  • 2
    Task.Delay is not a good way for waiting to get size properties. Instead I would rather subscribing to the EventHandler 'SizeChanged' of a view like that: SizeChanged += (sender, e) => {...}; – Nicolas Bodin Feb 13 '18 at 11:53
6

I would like to create a static struct in the shared code, so I can access the screen width/height values easily (as well as doing bindings in xAML).

The struct in the app namespace (e.g. in App.xaml.cs):

using System;
using Xamarin.Forms;
namespace YourAppName {
    ...
    public struct Constant {
        public static double ScreenWidth = Application.Current.MainPage.Width;
        public static double ScreenHeight = Application.Current.MainPage.Height;
    }
}

Retrieving screen width in C#:

var labelWidth = Constant.ScreenHeight * 0.2;
// then do something with labelWidth

Retrieving screen width in XAML:

<Label Text="Text with insane font size" FontSize="{Binding Source={x:Static local:Constant.ScreenWidth}}"/>
karel
  • 5,489
  • 46
  • 45
  • 50
Patrick
  • 1,717
  • 7
  • 21
  • 28
3

Another approach would be to use the override "OnSizeAllocated" for your page and then take the height and width according to the changes on the user's screen. You can create a static class to set the height and width of your screen everytime it changes and then access them from this class when needed.

The static class to set and access the device dimension:

public static class ScreenDimensions
{
    public static double Height { get; set; }
    public static double Width { get; set; }
}

Override to obtain the screen dimensions:

protected override void OnSizeAllocated(double width, double height)
{
    base.OnSizeAllocated(width, height);
    ScreenDimensions.Height = height;
    ScreenDimensions.Width = width;
}
Sparsha Bhattarai
  • 693
  • 11
  • 20
1

I Guess that the best way is use the xamarin.forms.Device information.

               Size size = Device.Info.PixelScreenSize;

            if (size.Width <= 720 && size.Height <= 1280)
            {
                stkLayoutTop.Margin = new Thickness(5, 30, 10, 0);
            }
            else
            {
                stkLayoutTop.Margin = new Thickness(5, 50, 10, 0);
            }
Igor Monteiro
  • 933
  • 1
  • 11
  • 29