Optimising layout for big screens

The Nokia Lumia 1520 and Nokia Lumia 1320 introduce large 6 inch displays to Lumia device portfolio. This section focuses on optimising applications for such large displays, and describes how to detect screen size and control application layouts using styles at runtime. These solutions are demonstrated in practice in Dynamic Layout Sample code.

It is also important that developers provide high enough resolution assets to avoid up-scaling of low resolution images: up-scaling becomes more apparent with large screens. See chapter Resolution specific considerations for advice on how to provide high resolution graphics.

On the 6" devices, the UI of the application can be optimised for these devices to not only improve look and feel, but also to take advantage of the larger real estate in order to offer more information in one screen. The designer of the application may also want to take into consideration that depending on how the user holds the device, some areas of the large display will not be very easy to access with one hand or, for example, with the thumb when playing a game in landscape mode.

How to detect big screen at runtime?

The following class and its only method shows how an application can determine at runtime whether the device has a "big screen":

...

class ScreenSizeHelper
{
    static private double _screenSize = -1.0f;
    static private double _screenDpiX = 0.0f;
    static private double _screenDpiY = 0.0f;
    static private Size _resolution;

    static public bool IsBigScreen
    {
        get
        {
            // Use 720p emulator to simulate big screen.
            if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator)
            {
                _screenSize = (App.Current.Host.Content.ScaleFactor == 150) ? 6.0f : 0.0f;
            }

            if (_screenSize == -1.0f)
            {
                try
                {
                    _screenDpiX = (double)DeviceExtendedProperties.GetValue("RawDpiX");
                    _screenDpiY = (double)DeviceExtendedProperties.GetValue("RawDpiY");
                    _resolution = (Size)DeviceExtendedProperties.GetValue("PhysicalScreenResolution");

                    // Calculate screen diagonal in inches.
                    _screenSize = 
                        Math.Sqrt(Math.Pow(_resolution.Width / _screenDpiX, 2) + 
                                  Math.Pow(_resolution.Height / _screenDpiY, 2));
                }
                catch (Exception e)
                {
                    // We're on older software with lower screen size, carry on.
                    Debug.WriteLine("IsBigScreen error: " + e.Message);
                    _screenSize = 0;
                }
            }

            // Returns true if screen size is bigger than 5 inches - you may edit the value based on your app's needs.
            return (_screenSize > 5.0f);
        }
    }
}

The definition of "big screen" is subjective, and depending on the app, you may wish to optimise already for 5 inch screens or only for screens that are at least 6 inches, for example. The above code now returns true for "big screen" when the screen size is more than 5 inches, but the value is easy to change to apply to your app's needs.

Dynamic layout using styles - fit more content in a page

In most cases the existing application UI can be tweaked for big screen support by simply overriding the styles used in the application. The solution is illustrated in Dynamic Layout Sample.

The example loads a list of objects consisting of text and image. The layout of the list item is defined in SampleDataItemTemplate.xaml...

...
<DataTemplate x:Key="SampleDataItemTemplate">
    <Grid Margin="12,6,12,6" Style="{StaticResource GridItem}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Image Grid.Row="0" Source="{Binding DataImage}" Style="{StaticResource GridImage}" />

        <TextBlock Grid.Row="1"
                   Margin="0"
                   Style="{StaticResource LargeBoldText}"
                   Text="{Binding DataTitle}" />
    </Grid>
</DataTemplate>
...

...where the look and feel of each element is determined by a style defined in SampleDataItemStyleDefault.xaml.

...
<!-- Text -->
<Style x:Key="NormalText"
       BasedOn="{StaticResource PhoneTextNormalStyle}"
       TargetType="TextBlock" />

<Style x:Key="LargeBoldText" TargetType="TextBlock">
    <Setter Property="FontFamily" Value="Segoe WP Semibold" />
    <Setter Property="FontSize" Value="32" />
</Style>

<!-- Layout -->
<Style x:Key="GridImage" TargetType="Image">
    <Setter Property="Width" Value="204" />
    <Setter Property="Height" Value="204" />
</Style>

<Style x:Key="GridItem" TargetType="Grid">
    <Setter Property="Width" Value="204" />
</Style>
...

On big screen devices it is enough if the application overrides the relevant styles by merging one new resource dictionary which contains an optimised version of the same styles. In our example the styles are redefined in SampleDataItemStyle1080p.xaml.

...
<!-- Large Screen Overrides -->

<!-- Text -->
<Style x:Key="LargeBoldText" TargetType="TextBlock">
    <Setter Property="FontFamily" Value="Segoe WP Semibold" />
    <Setter Property="FontSize" Value="22" />
</Style>

<!--  Layout  -->
<Style x:Key="GridImage" TargetType="Image">
    <Setter Property="Width" Value="128 />
    <Setter Property="Height" Value="128" />
</Style>
<Style x:Key="GridItem" TargetType="Grid">
    <Setter Property="Width" Value="128" />
</Style>

The new style is loaded if needed using the StyleSelector class. ..

...
class StyleSelector
{
    static public void SetStyle()
    {
        if(ScreenSizeHelper.IsBigScreen)
        {
            var appTheme = new ResourceDictionary {
                Source = new Uri("/DynamicScreenStyle;component/Themes/SampleDataItemStyle1080p.xaml", UriKind.Relative)
            };
            
            Application.Current.Resources.MergedDictionaries.Add(appTheme);
        }
    }
}
...

...when called from App's constructor:

public partial class App : Application
{
    ...

    public App()
    {
        // Global handler for uncaught exceptions.
        UnhandledException += Application_UnhandledException;

        // Standard XAML initialization
        InitializeComponent();

        // Load 1080p style if needed
        StyleSelector.SetStyle();

        ...
    }
    ...
}

Once loaded, the new resource will be added to the end of the resource dictionary list and thus will be the first in the searching order of style definition. The styles defined in this new dictionary will override previous definitions and thus the desired layout can be applied. If no new style is loaded, the app continues to render the UI using the layout based on the styles defined in SampleDataItemStyleDefault.xaml.

For enabling the layout change in UI designer or Blend, the layout override can be added to App.xaml's resource dictionary:

...
<!--Application Resources-->
<Application.Resources>
    <ResourceDictionary>
        <local:LocalizedStrings  x:Key="LocalizedStrings"/>
        <local:SampleModel x:Key="SampleModel" />
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="SampleDataTemplate.xaml" />
            <ResourceDictionary Source="Themes/SampleDataItemStyleDefault.xaml" />
            <!-- Enable the line below to see the 1080p layout overrides in designer. -->
            <!-- Comment it out for final build as the 1080p style overrides are to -->
            <!-- be activated on device by StyleSelector. -->
            <ResourceDictionary Source="Themes/SampleDataItemStyle1080p.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
...

The result:

Figure 1. Default layout presents items in 2 columns

Figure 2. On large display 3 columns are used to present items


Last updated 5 November 2013

Back to top

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×