如何根据 Android 上的像素密度正确设置字体大小/元素宽度?

问题描述 投票:0回答:1

我目前正在开发一个 .Net Maui android 应用程序,但我遇到了 FontSizes 的障碍。

部署应用程序并在许多不同的手机上尝试后,我开始意识到相同尺寸的屏幕通常具有不同的像素密度,并且布局会根据像素密度和屏幕尺寸而变得疯狂。

例如,当我检查DeviceDisplayInfo时,平板电脑等大屏幕手机的“高度”比普通尺寸的手机小。而完全相同的屏幕尺寸,不同的像素密度,只会让所有的布局“缩小”。

我会给你一个带有图像的例子,以便你更好地理解。

这是在具有“基本”规格的 Google Pixel 5 模拟器上运行的应用程序的打印屏幕:

base density image

这是在 Google Pixel 5 上完全相同的屏幕上打印的照片,但像素密度为 560,而不是基础 440:

560 density Image

正如您在较高像素密度模拟器中看到的,整个布局太大了。

我尝试使用屏幕尺寸(高度/宽度)和密度进行一些计算,但没有得出最终结论,它根据屏幕尺寸和密度而变化很大。

我实际上能够为页面的组件创建特定的样式(小/中/大,例如,使用不同的字体大小/高度等),并根据屏幕尺寸动态地更改它们。我就是这样做的。

 protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        double ScreenSize = this.Height;
                
        //Also tried doing something like this but wasn't helping me in any way
        //ScreenSize = (DeviceDisplay.Current.MainDisplayInfo.Height /  DeviceDisplay.Current.MainDisplayInfo.Density); 

        if(ScreenSize < 0)
            return;
      

        if (ScreenSize >= 900) 
            SetSizesLarge();
        if (ScreenSize > 600 && ScreenSize  < 900)
            SetSizesMedium();
        if (ScreenSize < 600)
            SetSizesSmall();
    }
    private void SetSizesLarge()
    {
        WelcomeHeaderLabel.Style = ResourceHelper.FindResource(this, "ActiveHeaderStyleLarge") as Style;
        Go_Natural_Bottom_Logo.WidthRequest = (double) 200;
        
    }
    private void SetSizesMedium()
    {
        WelcomeHeaderLabel.Style = ResourceHelper.FindResource(this, "ActiveHeaderStyle") as Style;

        Go_Natural_Bottom_Logo.WidthRequest = (double)150;
    }
    private void SetSizesSmall()
    {
        WelcomeHeaderLabel.Style = ResourceHelper.FindResource(this, "ActiveHeaderStyleSmall") as Style;

        Go_Natural_Bottom_Logo.WidthRequest = (double)120;
    }

那么,我如何知道何时根据手机尺寸/像素密度使用小/中/大布局?

c# android layout size maui
1个回答
0
投票

当我遇到类似的情况时,起初我尝试设置

Label.FontAutoScalingEnabled="True"
,但很惊讶它实际上并没有做这样的事情。因此,在我发现一些内置的自动缩放方式之前,我进行了自己的二分搜索。这可能是你可以适应你想做的事情的东西。


public partial class MainPage : ContentPage
{
    public MainPage() => InitializeComponent();

    private void AnySizeChanged(object sender, EventArgs e)
    {
        if(sender is Label label)
        {
            double minFontSize = 1;
            double maxFontSize = 100;
            double tolerance = 0.1;
            double targetHeight = label.Height * 0.9;
            double targetWidth = label.Width * 0.8; 

            while (minFontSize < maxFontSize)
            {
                double midFontSize = (minFontSize + maxFontSize) / 2;
                label.FontSize = midFontSize;
                Size textSize = label.Measure(double.PositiveInfinity, double.PositiveInfinity).Request;
                bool isHeightWithinTolerance = Math.Abs(textSize.Height - targetHeight) <= targetHeight * tolerance;
                bool isWidthWithinLabel = textSize.Width <= targetWidth;

                if (isHeightWithinTolerance && isWidthWithinLabel)
                {
                    break;
                }
                else if (textSize.Height > targetHeight || textSize.Width > targetWidth)
                {
                    maxFontSize = midFontSize - 0.1;
                }
                else
                {
                    minFontSize = midFontSize + 0.1; 
                }
            }
            label.FontSize = (minFontSize + maxFontSize) / 2;
        }
    }
}

在xaml中,处理SizeChanged事件。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DynamicSizingProto"
             x:Class="DynamicSizingProto.MainPage">
    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="HorizontalTextAlignment" Value="Center" />
            <Setter Property="VerticalTextAlignment" Value="Center" />
            <Setter Property="Margin" Value="5" />
            <Setter Property="BackgroundColor" Value="{StaticResource Secondary}" />
            <Setter Property="TextColor" Value="{StaticResource Primary}" />
        </Style>
    </ContentPage.Resources>
    <Grid
        RowDefinitions="*,*,2*,3*,4*,*">
        <Label
            Text="Text Placeholder"
            SizeChanged="AnySizeChanged"
            Grid.Row="1"/>
        <Label
            Text="Text Placeholder"
            SizeChanged="AnySizeChanged"
            Grid.Row="2"/>
        <Label
            Text="Text Placeholder"
            SizeChanged="AnySizeChanged"
            Grid.Row="3"/>
        <Label
            Text="Text Placeholder"
            SizeChanged="AnySizeChanged"
            Grid.Row="4"/>
    </Grid>
</ContentPage>

我可能会尝试将其烘焙成自定义扩展

LabelEx
,但这是基本想法。

© www.soinside.com 2019 - 2024. All rights reserved.