Sizing objects based on screen dimensions

前端 未结 1 753
走了就别回头了
走了就别回头了 2020-12-18 16:36

Given different screen sizes what is the accepted method of scaling the UI?

In setting up a UI it looks great on one screen but terrible on another. Trying to set

相关标签:
1条回答
  • 2020-12-18 17:10

    If you want to change values of your UI depending on the platform, you could make use of the "On Platform" Statement. For instance, if you want to have a different margin for a grid on iOS than you need to use on Android, you could use it like that:

    <Grid>
        <Grid.Margin>
            <On Platform x:TypeArguments="Thickness">
                <On Platform="iOS">0,0,0,0</On>
                <On Platform="Android">15,0,15,0</On>
            </OnPlatform>
        </Grid.Margin>
    </Grid>
    

    Of course you can use that for other properties as well. Keep in mind that if you set a property in your view.xaml it will override the style definition of the same property if present.

    Making your font size dependent on the screen height can be done as follows:

    Getting the screen dimensions - Shared

    We will need to implement a dependency service, which allows us to retrieve the actual screen height or width.

    Therefore in the shared code, create a new interface:

    IScreenDimensions.cs

    public interface IScreenDimensions
    {
        double GetScreenWidth();
        double GetScreenHeight();
    }
    

    in your android implementation, add the implementation of the interface:

    Getting the screen dimensions - Android

    ScreenDimensions.cs

    [assembly: Dependency(typeof(ScreenDimensions))]
    namespace MyAppNamespace.Droid
    {
        public class ScreenDimensions : IScreenDimensions
        {
            public double GetScreenHeight()
            {
                return ((double)Android.App.Application.Context.Resources.DisplayMetrics.HeightPixels / (double)Android.App.Application.Context.Resources.DisplayMetrics.Density);
            }
    
            public double GetScreenWidth()
            {
                return ((double)Android.App.Application.Context.Resources.DisplayMetrics.WidthPixels / (double)Android.App.Application.Context.Resources.DisplayMetrics.Density);
            }
        }
    }
    

    Getting the screen dimensions - iOS

    ScreenDimensions.cs

    [assembly: Dependency(typeof(ScreenDimensions))]
    namespace MyAppNamespace.iOS
    {
        public class ScreenDimensions : IScreenDimensions
        {
            public double GetScreenHeight()
            {
                return (double)UIScreen.MainScreen.Bounds.Height;
            }
    
            public double GetScreenWidth()
            {
                return (double)UIScreen.MainScreen.Bounds.Width;
            }
        }
    }
    

    Building a value converter to consume the screen dimensions

    Now we create an IValueConverter (again in shared code):

    ScreenSizeToRelativeSizeConverter.cs

    public class ScreenSizeToRelativeSizeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double height = DependencyService.Get<IScreenDimensions>().GetScreenHeight();
            return (double) height * (double) parameter;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // no need to convert anything back
            throw new NotImplementedException();
        }
    }
    

    Note that the converter needs a parameter that will tell it which fraction of the screen size the resulting size will end up with.

    Putting it all together

    Finally you add the following resources to your App.xaml file:

    <Application.Resources>
        <ResourceDictionary>
            <converter:ScreenSizeToRelativeSizeConverter x:Key="SizeToRelativeSizeConverter"/>
            <x:Double x:Key="fontSizeFactor">0.03</x:Double>
            <Style x:Key="LabelStyle" TargetType="Label">
                <Setter Property="FontSize" Value="{Binding Converter={StaticResource SizeToRelativeSizeConverter}, ConverterParameter={StaticResource fontSizeFactor}}" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
    

    And set the style to your label (or other element) in question:

    <Label Text="Welcome to Xamarin.Forms!" Style="{StaticResource LabelStyle}"
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
    
    0 讨论(0)
提交回复
热议问题