Xamarin.Forms’ layout classes and options offer a powerful toolset for arranging visual elements on the mobile screen. In rare cases, however, you might want to compute positions or dimensions based on the current screen size. In the following example we want to create a set of colored squares that exactly fill the screen width, which is hardly doable without computing any lengths. Furthermore, defining the WidthRequest and HeightRequest is often significantly faster than leaving the layout negotiation to Xamarin.Forms.
A handy solution is to define a publicly accessible static ScreenSize property in some public class, e.g. App:
public static Size ScreenSize;
Since there is currently no platform-independent way to get the screen size, we initialize this property during FinishedLaunching on iOS:
App.ScreenSize = new Size(UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
and OnCreate on Android:
App.ScreenSize = new Size(
Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density,
Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density);
both right before calling the App constructor. Note that we need to consider the pixel density in order to get device-independent pixels.
The platform-independent App class will contain a grid of colored squares. Therefore, we define the page padding (the space between grid and screen boundary), grid spacing (the space between neighboring grid cells) as well as row and column count as constant class members:
const int padding = 10;
const int spacing = 5;
const int count = 5;
In the constructor, when the ScreenSize has been defined by the above-mentioned lines of code, we can compute the boxSize of a single square.1 Furthermore, we create a new ContentPage filled with a custom ColorGrid. Padding and spacing are set as defined above.
public App()
{
var boxSize = (ScreenSize.Width - 2 * padding + spacing) / count - spacing;
MainPage = new ContentPage {
Padding = padding,
Content = new ColorGrid(boxSize, count, count) {
RowSpacing = spacing,
ColumnSpacing = spacing,
VerticalOptions = LayoutOptions.CenterAndExpand,
},
};
}
The ColorGrid is derived from the Xamarin.Forms layout Grid. The constructor takes three parameters: the size of each grid cell and the number of rows and columns. Two nested for loops add the requested number of cells. Each cell is a BoxView with pre-defined size and a color depending on its row and column indices.
public class ColorGrid: Grid
{
public ColorGrid(double boxSize, int rows, int columns)
{
for (var row = 0; row < rows; row++)
for (var column = 0; column < columns; column++) {
var box = new BoxView {
Color = Color.FromRgb(row * 256 / rows, column * 256 / columns, 127),
WidthRequest = boxSize,
HeightRequest = boxSize,
};
Children.Add(box, row, column);
}
}
}