Summary of Chapter 5. Dealing with sizes

PDF for offline use
Related Samples:
Related Links:

Let us know how you feel about this

Translation Quality


0/250

last updated: 2017-11

Several sizes in Xamarin.Forms have been encountered so far:

  • The height of the iOS status bar is 20
  • The BoxView has a default width and height of 40
  • The default Padding in a Frame is 20
  • The default Spacing on the StackLayout is 6
  • The Device.GetNamedSize method returns a numeric font size

These sizes are not pixels. Instead, they are device-independent units recognized independently by each platform.

Pixels, points, dps, DIPs, and DIUs

Early in the histories of the Apple Mac and Microsoft Windows, programmers worked in units of pixels. However, the advent of higher-resolution displays required a more virtualized and abstract approach to screen coordinates. In the Mac world, programmers worked in units of points, traditionally 1/72 inch, while Windows developers used device-independent units (DIUs) based on 1/96 inch.

Mobile devices, however, are generally held much closer to the face and have a higher resolution than desktop screens, which implies that a greater pixel density can be tolerated.

Programmers targeting Apple iPhone and iPad devices continue to work in units of points, but there are 160 of these points to the inch. Depending on the device, there may be 1, 2, or 3 pixels to the point.

Android is similar. Programmers work in units of density-independent pixels (dps), and the relationship between dps and pixels is based on 160 dps to the inch.

The Windows Runtime has also established scaling factors that imply something close to 160 device-independent units to the inch.

In summary, a Xamarin.Forms programmer targeting phones and tablets can assume that all units of measurement are based on the following criterion:

  • 160 units to the inch, equivalent to
  • 64 units to the centimeter

The read-only Width and Height properties defined by VisualElement have default "mock" values of –1. Only when an element has been sized and accommodated in layout will these properties reflect the actual size of the element in device-independent units. This size includes any Padding set on the element but not the Margin.

A visual element fires the SizeChanged event when its Width or Height has changed. The WhatSize sample uses this event to display the size of the program's screen.

Metrical sizes

The MetricalBoxView uses WidthRequest and HeightRequest to display a BoxView one inch tall and one centimeter wide.

Estimated font sizes

The FontSizes sample shows how to use the 160-units-to-the-inch rule to specify font sizes in units of points. The visual consistency among the platforms using this technique is better than Device.GetNamedSize.

Fitting text to available size

It's possible to fit a block of text within a particular rectangle by calculating a FontSize of the Label using the following criteria:

  • Line spacing is 120% of the font size (130% on the Windows platforms).
  • Average character width is 50% of the font size.

The EstimatedFontSize sample demonstrates this technique. This program was written before the Margin property was available, so it uses a ContentView with a Padding setting to simulate a margin.

Triple screenshot of estimated font size

A fit-to-size clock

The FitToSizeClock sample demonstrates using Device.StartTimer to start a timer that periodically notifies the application when it's time to update the clock. The font size is set to one-sixth of the page width to make the display as large as possible.

Accessibility issues

The EstimatedFontSize program and the FitToSizeClock program both contain a subtle flaw: If the user changes the phone's accessibility settings on Android or Windows 10 Mobile, the program no longer can estimate how large the text is rendered based on the font size. The AccessibilityTest sample demonstrates this problem.

Empirically fitting text

Another way to fit text to a rectangle is to empirically calculate the rendered text size and adjust it up or down. The program in the book calls GetSizeRequest on a visual element to obtain the element's desired size. That method has been deprecated, and programs should instead call [Measure] (/api/member/Xamarin.Forms.VisualElement.Measure/p/System.Double/System.Double/Xamarin.Forms.MeasureFlags/).

For a Label, the first argument should be the width of the container (to allow wrapping), while the second argument should be set to Double.PositiveInfinity to make the height unconstrained. The EmpiricalFontSize sample demonstrates this technique.

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.