我可以使用 ICanvas.GetStringSize 方法在 IDrawable 对象的 Draw 方法调用中测量文本字符串大小。
现在,如果我需要在绘图之前测量文本字符串怎么办?例如,在我的用例中,可绘制对象的边界框(Draw 方法调用中的第二个参数)由给定字体大小的父 ContentView 设置,方法是计算文本可以采用的最大大小此字体大小的字符串。这用下面的伪代码来说明:
private void OnFontSizeChanged(int fontSize)
{
// The string possible values are integers in the [1-9999] range
var maxTextSize = GetStringSize("9999", fontSize);
// Now we know the font size, we can set the GraphicsView object size once
// according to the maximum width/height that can be taken by the child drawing.
HeightRequest = maxTextSize.Height * 1.2f;
WidthRequest = maxTextSize.Width * 1.2f;
}
在我描述的场景中,有没有一种方法可以不使用 ICanvas 来测量文本大小?感谢您对此的任何意见。
我在我的一个项目中使用了
Label.Measure
,试图进行一些响应式字体缩放。您也许可以根据您的目的对其进行调整。就我而言,基本思想是根据测量的大小进行二分搜索。
根据一些初步实验,如果想使用虚拟标签进行测量,似乎标签“does”需要位于可视化树中的某个位置,但“doesn't”需要可见。
<?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
,但这是基本想法。
iPad
现在已经计算了大小,GraphicsView 调用 Invalidate,因此再次调用 Draw 方法,但现在知道了不同图形元素的适当大小。
图形查看代码:
public ValueOutOfTotal()
{
Drawable = ValueOutOfTotalDrawable = new ValueOutOfTotalDrawable();
SizeChanged += ValueOutOfTotal_SizeChanged;
ValueOutOfTotalDrawable.RequiredSizeComputed += ValueOutOfTotalDrawable_RequiredSizeComputed;
}
private void ValueOutOfTotalDrawable_RequiredSizeComputed(object? sender, EventArgs e)
{
if (e is SizeComputedEventArgs sizeComputedEventArgs)
{
Invalidate();
}
}
private void ValueOutOfTotal_SizeChanged(object? sender, EventArgs e)
{
ValueOutOfTotalDrawable.MustComputeRequiredSize = true;
}
IDrawable 代码:(ComputeRequiredSize 方法当然要使用有关您要绘制的内容的信息来实现)
public void Draw(ICanvas canvas, RectF dirtyRect)
{
if (MustComputeRequiredSize)
{
_sizeInfo = ComputeRequiredSize(canvas, dirtyRect);
MustComputeRequiredSize = false;
RequiredSizeComputed?.Invoke(this, EventArgs.Empty);
}
else
{
Draw(canvas, dirtyRect, ValueColor, TotalColor, SeparatorColor, TitleColor, ValueFontSize, TotalFontSize, TitleFontSize, Value, Total, Title, _sizeInfo);
}
}