我需要知道一段文本的确切范围-相当于Android的getTextBounds。我意识到这与Flutter的设计有些背离,但是我以非传统的方式使用文本(例如,将文本以精确的位置和大小嵌入艺术图片中)。
我尝试了三种方法:
TextPainter
的{{1}}和minIntrinsicWidth
。资料来源如下。这将产生一个bounding box with space on all sides(由于没有10个声望点,因此无法直接链接到图像)。我需要该矩形的边紧靠“ 8”的黑色像素。 (在这种特殊情况下,height
和width
的值与maxIntrinsicWidth
相同;而且,minIntrinsicWidth
的值与preferredLineHeight
相同。)
height
的{{1}}-与TextPainter的结果基本相同。
Paragraph
-不管getBoxesForRange
枚举值如何,都留有空格。我以this answer为起点。
FittedBox
代码如下。 (我意识到这是低效率的;在获得所需的边界框之前,我不在乎。我使用Scene / Picture / etc是为了希望在较低级别找到合适的功能。)
BoxFit
答案 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的结果是否包含少量填充,尽管如果包含,则已经提出的解决方案也可能包含填充。