Windows Store通用应用程序(W8.1 + WP8.1)中字体大小的缩放

20
如何在 Windows Store Universal App (W8.1 + WP8.1) 中缩放文本?基本上,无论使用哪个设备/分辨率,应用程序应该看起来相同。目前的情况是,布局(动态网格布局)和图像缩放良好,但文本(字体大小)不行。虽然显示的文本在 WVGA 分辨率下(480×800)很好看,但对于 1080p 分辨率来说太小了。我已经阅读了很多类似“针对像素密度进行缩放的指南”“支持多种屏幕尺寸的指南”的材料,但仍然不知道如何缩放文本以保持可读性,而与显示分辨率/ DPI 无关。当然,我可以编写一个类,该类使用DisplayInformation.ResolutionScale属性将字体大小转换为适当的值。例如:FontSize 16 在 WVGA 上使用 ScaleFactor 1x 等于 FontSize 16,FontSize 16 在 WXGA 上使用 ScaleFactor 1.6x 等于 FontSize 25.6,FontSize 16 在 720p 上使用 ScaleFactor 1.5x 等于 FontSize 24,FontSize 16 在 1080p 上使用 ScaleFactor 2.25x 等于 FontSize 36。但我不确定这对所有情况都有效。有更好的方法吗?我认为这样一个常见的任务可以使用一些内置功能来实现。免责声明:这(希望如此)不是一个“让我为您谷歌这个问题”问题。我找到了大量涉及缩放的页面,但它们都涵盖布局或图像。但我找不到关于字体大小缩放的任何内容。如果我错过了什么,请原谅我。 编辑:我担心自己没能清楚地表达问题:(WVGA 在左,1080p 在右)

4
你解决了吗?我也有同样的问题,找不到任何好的信息。 - Andreas Bergqvist
不,我没有。我在想其他开发者是如何解决这个问题的。也许我们走错了方向? - Joel
看起来我也有同样的问题,找不到解决办法... - Laserson
5个回答

8
我为我的 Windows Store 应用程序所做的是将字体大小绑定到页面高度,并转换该值(您需要尝试一下,直到找到适合您情况的正确值)。
<TextBlock Grid.Row="0" Text="Some Text" 
FontSize="{Binding ElementName=pageRoot, Path=ActualHeight, 
Converter={StaticResource PageHeightConverter}, ConverterParameter='BodyFontSize'}" />

这是我的转换器类:

    class PageHeightConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        switch ((string)parameter)
        {
            case "HeroImage":
                return ((((double)value) * 2) / 3);
            case "TitleFontSize":
                return (int)((double)value / 40);
            case "BodyFontSize":
                return (int)((double)value / 60);
            default:
                return 0;
        }
    }
}

这不是完美的,但在我找到更好的解决方案之前,它相当不错。


6

我发现使用IValueConverter方法与ResolutionScale属性结合使用时效果非常好:

class ScaleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var resolutionScale = (int)DisplayInformation.GetForCurrentView().ResolutionScale / 100.0;
        var baseValue = int.Parse(parameter as string);
        var scaledValue = baseValue * resolutionScale;
        if (targetType == typeof(GridLength))
            return new GridLength(scaledValue);
        return scaledValue;
    }
}

请注意,如果您使用FontSize(如我还将其用于ColumnDefinition.Width),您需要处理返回正确类型的输出。
我的XAML使用类似于这样:
<TextBlock Text="string" FontSize="{Binding ElementName=root, Path=ActualHeight, Converter={StaticResource ScaleConverter}, ConverterParameter='30'}" />

而为了完善此解决方案,对于每个在XAML页面中使用它的组件,您需要包含以下内容,并将SwapChainBackgroundPanel替换为您正在使用的任何类,并正确定义XML命名空间:

<SwapChainBackgroundPanel.Resources>
    <local:ScaleConverter x:Key="ScaleConverter"></local:ScaleConverter>
</SwapChainBackgroundPanel.Resources>

2
WinRT可以自动缩放所有运行在其上的内容,并根据显示器的像素密度进行缩放。在Windows 8.0中,它通常会按照100%、140%和180%进行缩放,新版本可能会有更多的缩放比例。我认为您无法选择退出此缩放。
如果您不想使用系统级别的内置缩放功能,则基本上只能自己动手。您可以通过设置字体大小手动缩放文本,或者您可以利用变换的威力来缩放文本或整个UI。

3
UI可以很好地自动适配,但字体大小是个问题。我该如何在W8.1和WP8.1中启用字体大小自适应? - Joel
字体大小也会被WinRT自动缩放。尝试进入“设置”->“PC和设备”->“显示”->“更多选项”,选择默认/较大,看看差异。 - Kasper Holdum

1
你的样本图片是误导性的,因为设备的实际大小也会有所不同。这篇博客文章告诉你如何设置模拟器以获得更准确的表示。
如果你想在每个屏幕上显示完全相同的内容(即,6英寸手机只显示4英寸手机的放大版本,而不是显示50%更多的内容),那么使用ViewBox来缩放你的应用程序。但这不是一个特别好的用户体验。

0

我正在等待答案,并已经发布了一个相关的问题。
作为临时解决方案,我使用了iValueConverter,在某些分辨率下可以工作,但在其他情况下则不行。

我的iValueConverter如下:

class FontSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
    {
    var display = Helpers.ScreenResolution();
    var height = display.Height;
    var oldFontSize = (int)value;
    if(oldFontSize == null) return;

    // Calculate the new Fontsize based on the designed Fontsize
    // and design display size in Visual Studio designer...
    var newFontSize = (int)Math.Round((oldFontSize / 768.0) * height, 0);
    return newFontSize;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
    throw new NotImplementedException();
}}

希望这能有所帮助...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接