颤振:找到文本的确切范围

时间:2018-08-16 17:40:59

标签: flutter

我需要知道一段文本的确切范围-相当于Android的getTextBounds。我意识到这与Flutter的设计有些背离,但是我以非传统的方式使用文本(例如,将文本以精确的位置和大小嵌入艺术图片中)。

我尝试了三种方法:

  • TextPainter的{​​{1}}和minIntrinsicWidth。资料来源如下。这将产生一个bounding box with space on all sides(由于没有10个声望点,因此无法直接链接到图像)。我需要该矩形的边紧靠“ 8”的黑色像素。 (在这种特殊情况下,heightwidth的值与maxIntrinsicWidth相同;而且,minIntrinsicWidth的值与preferredLineHeight相同。)

  • height的{​​{1}}-与TextPainter的结果基本相同。

  • Paragraph-不管getBoxesForRange枚举值如何,都留有空格。我以this answer为起点。

FittedBox代码如下。 (我意识到这是低效率的;在获得所需的边界框之前,我不在乎。我使用Scene / Picture / etc是为了希望在较低级别找到合适的功能。)

BoxFit

2 个答案:

答案 0 :(得分:1)

要忽略该填充,您必须进行{strong>真正的低级调用,因为Text和空格实际上是一起绘制的。我尝试搜索Internet上是否还有其他出路,但找不到任何可以真正解决您问题的方法。

我尝试遍历Flutter SDK(Widget_Library)的源代码,但我只能看到最终生成的小部件是RichText,其源代码几乎消失了。 (我只是在GitHub上搜索时找不到该小部件的定义...在Android Studio中,您可以将鼠标悬停在其上并按Ctrl+LeftClick来获得对该小部件的一些引用。但是我很确定根据字体的字体(将是.ttf或.otf文件...以两种方式将它们连同您所引用的填充一起绘制),您将带您进入另一个未知的世界。

您现在所要做的就是创建我们自己的字符集小部件,该小部件接受原始字符串并读取每个字符,并使用一些自定义绘制功能绘制您已经定义的数字/字符,

或者如果您准备放开该填充以节省一些时间(这对您现在可能至关重要,现在可能就不重要了),则可以使用一些预定义的函数将其与空格一起使用,或者使用以下解决方案来获得您想要的任何小部件的尺寸。

  

我需要知道一段文本的确切范围...

了解任何窗口小部件宽度的最简单方法是使用GlobalKey

声明并初始化变量以存储GlobalKey,

GlobalKey textKey = GlobalKey();

GlobalKey传递到Text小部件的关键参数,

Text(
  "hello",
   key: textKey,
 )

现在,我将用GestureDetector包裹上面的小部件,以打印上面的小部件的宽度。

GestureDetector(
  onTap: (){
    print(textKey.currentContext.size.width); //This is your width
    print(textKey.currentContext.size.height); //This is your height
      },
   child: Text(
     "hello",
     key: textKey,
       ),
     )

正如我前面提到的,您可以在任何小部件上使用它,因此也可以在TextSpan小部件上使用它:

GestureDetector(
  onTap: (){
    print(textKey.currentContext.size.width); //This is your width
      },
TextSpan(
      key: textKey,
      text: '8',
      style: new TextStyle(
        color: black,
        fontSize: 200.0,
        fontFamily: "Roboto",
      ),
    ),
  )

现在,借助GlobalKey(),您可以获得有关Text的所有信息,并相应地绘制边界/矩形。

注意:GlobalKey()为您的小部件提供了唯一的标识,因此请勿在多个小部件上重复使用它。

=================

编辑:

如果能够以某种方式获得应用程序/文本中每个像素的颜色,那么就有可能获得您想要实现的目标。

注意:您必须分别查找每侧的偏移/填充。

x1,y1是容器起点的坐标,x2,y2是容器终点。

minL,minR,minT,minB是您要查找的偏移量。

基本逻辑:根据所考虑的面垂直/水平扫描每行,直到获得一个颜色等于文本颜色的像素,然后对所有虚线进行此操作,直到获得最小偏移量(文本距离)为止从边界开始)。

想象一下,从容器的边界开始绘制一条线,直到遇到文本的一个边界(/达到文本的颜色),然后对所有其他水平(水平[左/右]或垂直[顶部/底部])行,您只需要记住最短的距离即可。

// Left Side
for(i=y1+1;i<y2;i++)
 for(j=x1+1;j<x2;j++)
   if(colorof(j,i)==textcolor && minL>j) {minL = j; break;}

// Right Side
for(i=y1+1;i<y2;i++)
 for(j=x2-1;j>x1;j--)
   if(colorof(j,i)==textcolor && minR>j) {minR = j; break;}

// Top Side
for(i=x1+1;i<x2;i++)
 for(j=y1;j<y2;j++)
   if(colorof(i,j)==textcolor && minT>j) {minT = j; break;}

// Bottom Side
for(i=x1+1;i<x1;i++)
 for(j=y2;j>y1;j--)
   if(colorof(i,j)==textcolor && minB>j) {minB = j; break;}

x1 = x1 + minL;
y1 = y1 + minT;
x2 = x2 - minR;
y2 = y2 - minB;

在实现上述逻辑时,请确保没有其他重叠/底层的小部件(脚手架/堆栈组合),其颜色与文本颜色相匹配。

答案 1 :(得分:0)

您可以使用TextPainter类确定某些文本的宽度。  https://api.flutter.dev/flutter/painting/TextPainter-class.html Flutter在布局期间使用它来确定文本窗口小部件的大小。

不确定TextPainter的结果是否包含少量填充,尽管如果包含,则已经提出的解决方案也可能包含填充。