【问题标题】:Xamarin.Forms - How to copy Label and size with Measure()? Trying to auto size font. (Head scratcher!)Xamarin.Forms - 如何使用 Measure() 复制标签和大小?尝试自动调整字体大小。 (挠头!)
【发布时间】:2020-08-31 10:01:44
【问题描述】:

有一个很棒的 Xamarin.Forms 示例项目,标题为 Empirical Font Size,它可以计算 Label 在其包含视图中的最大可能字体大小。它获取有问题的标签,使用VisualElement.Measure() 根据其属性获取标签的一些大小请求,并将请求的大小与容器的大小进行比较,以查看标签是否适合该字体大小。它会重新计算,直到找到最合适的。它工作得很好,但我想修改它以做更多。

不幸的是,我在修改中遇到了一些令人讨厌的障碍,我不确定它们是否与 C# 或 Xamarin 相关。这就是我想做的事情。

  • 将计算提取到他们自己的函数中,以便在任何地方使用。 -> 原版不这样做。这一点实际上已经完成,但以下目标不起作用,因此最好将此作为起点。
  • (FOCUS HERE) 避免在函数中使用原始标签数据。 (复制一份。) -> 我正在添加一些功能,这些功能需要我在尺寸计算期间主动更改标签文本数据,但修改我正在调整尺寸的标签可能会导致问题(并非总是与尺寸有关,但在其他方面)。我需要一种方法来复制字体大小的标签以保护原始数据。 (更多关于我在下面尝试过的内容)。
  • 抽象函数以允许调整其他视图的大小。 -> 现在,这仅计算最大标签字体大小。如果可能的话,我想支持其他视图(如选择器、条目等)的自动字体大小调整。在弄清楚 #2 时深思熟虑。

目标 #2 是我遇到问题的地方。我找不到复制标签然后对临时副本执行尺寸计算的方法。以下是我尝试过的方法以及每次尝试失败的原因。

  • 制作一个浅拷贝。(例如Label copyLabel = origLabel;)-> 正如预期的那样,这不起作用,因为新的标签副本仍在引用内存中相同的原始标签数据。所以如果我设置copyLabel.Text = "hello",那么origLabel.Text也会变成“hello”。不好。
  • JSON 复制 -> 我见过recommendations to use JSON converters 序列化然后反序列化一个视图以便快速进行深度复制,但是当我尝试这个时遇到了异常。关于标签的孩子的self-referencing loop。(标签甚至有孩子吗??)
  • ICloneable -> 我将在静态类中运行这个函数,所以我不能这样做。不过,这可能并不重要,因为下一次尝试。
  • 创建一个新的 Label 对象并复制一些值。 -> 这似乎可行,但这里的问题是 VisualElement.Measure() 计算。新标签缺少计算正常工作所需的内容,我不知道那是什么。

要使其中任何一个起作用,我需要复制标签,立即对副本执行计算,然后将生成的字体大小应用于原件。然后副本消失。噗!不幸的是,我制作的任何副本都会导致不同的计算,所以这就是我目前遇到的问题。

有人在其他地方提到,可能调整大小不起作用,因为新标签不是布局的一部分,因此无法调整大小,但他们没有解释,所以我不明白他们的意思.

要查看哪些有效,哪些无效,这里有一个小型 Xamarin 示例项目,其中包含 Empirical Font Size 项目的修改版本。这是一个简单的 A/B 测试。具有相同文本的两个标签由两个几乎相同的函数调整大小 - 一个使用原始标签,一个尝试使用副本。它们应该填充提供的堆栈布局的上半部分和下半部分,但副本不起作用。我需要帮助来完成这项工作。

修改后的示例项目: https://drive.google.com/file/d/1mWxE3p6u53jkIdaIEFVFnkI7BC-kfske/view?usp=sharing

【问题讨论】:

    标签: c# xamarin xamarin.forms label measure


    【解决方案1】:

    我为这个问题找到了一个安全、简单的解决方法,我称之为“ghost sizing”。您可以创建一个不可见的“幽灵标签”,并将其放置到将调整标签大小的页面中。它是不可见的,所以它根本不会改变布局,但它仍然可以用于尺寸计算。您将要调整大小的标签文本传递给幻影标签,将幻影标签调整到所需的空间,然后将返回的尺寸值应用于目标标签。

    XAML:

    <!--  for sizing other elements without breaking bindings  -->
    <Label x:Name="ghostLabel" IsVisible="false" />
    

    C# 代码隐藏:

    ghostLabel.Text = String.Copy(myLabel.Text);
    
    ...
    double labelFontSize = ...// do font size calculations here using the ghostLabel object
    ...
    
    myLabel.FontSize = labelFontSize;
    

    如果您对此感到好奇,我已经为此制作了自己的字体大小调整类。

    Github repo

    further ghost sizing notes

    【讨论】:

      猜你喜欢
      • 2021-10-04
      • 2011-02-07
      • 2019-11-13
      • 1970-01-01
      • 2015-10-08
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多