我正在开发一个做布局的应用程序。并运行单元测试。TextPainter
为Android和单元测试返回不同的Size
。Sp做Paragraph
。
即使在设备和单元测试中将fontFamily
设置为Roboto-Black。(因为单元测试似乎不使用Roboto作为默认字体。
下面是计算字体大小的概述,有和没有Roboto-Black:
使用TextPainter对单词“test”的大小。
fontFamily: left empty, should be Roboto by default
Unit test: Size(400, 100)
Android: Size(171, 117) ----------<< +1 width
Chrome: Size(170, 117)
fontFamily: Roboto-Black
Unit test: Size(175, 120) ----------<< +3 height
Android: Size(175, 117)
Chrome: Size(175, 117)
使用段落的单词“test”的大小。
fontFamily: left empty, should be Roboto by default
Unit test: (200,200)
Android: (170.1, 117) -------<< + 0.2 width
Chrome: (169.9, 117)
fontFamily: Roboto-Black
Unit test: (174.31640625, 120) -------<< +3 height, +0.01640625 width
Android: (174.3, 117)
Chrome: (174.3, 117)
- 注意:* 单元测试期望与
174.31640625
进行比较,表明结果未按应有的四舍五入?174.3
未通过单元测试。
设备段落
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Builder(
builder: ((context) {
// ------------------------------------------------------
const styleCustom =
TextStyle(fontFamily: 'myDefaultFont', fontSize: 100);
const textCustom = Text('test', style: styleCustom);
const style = TextStyle(fontSize: 100);
const text = Text('test', style: style);
// ------------------------------------------------------
const constraints = ParagraphConstraints(width: 200);
final builderCustom = ParagraphBuilder(ParagraphStyle(
fontFamily: styleCustom.fontFamily,
fontSize: styleCustom.fontSize));
builderCustom.addText(textCustom.data!);
final paragraphCustom = builderCustom.build();
paragraphCustom.layout(constraints);
final sizeCustom =
Size(paragraphCustom.longestLine, paragraphCustom.height);
// ------------------------------------------------------
final builder =
ParagraphBuilder(ParagraphStyle(fontSize: style.fontSize));
builder.addText(text.data!);
final paragraph = builder.build();
paragraph.layout(constraints);
final size = Size(paragraph.longestLine, paragraph.height);
// ------------------------------------------------------
// fontFamily: '',
// Unit test: (200,200)
// Android: (170.1, 117) -------<< + 0.2 width
// Chrome: (169.9, 117)
print(size);
// fontFamily: 'myDefaultFont',
// Unit test: (174.31640625, 120) -------<< +3 height, +0.01640625 width
// Android: (174.3, 117)
// Chrome: (174.3, 117)
print(sizeCustom);
return Column(
children: [
text,
Text(size.toString()),
textCustom,
Text(sizeCustom.toString()),
],
);
}),
),
),
),
);
}
}
设备TextPainter
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Builder(builder: ((context) {
// myDefaultFont == Roboto-Black
const styleCustom =
TextStyle(fontFamily: 'myDefaultFont', fontSize: 100);
const textCustom = Text('test', style: styleCustom);
const style = TextStyle(fontSize: 100);
const text = Text('test', style: style);
// fontFamily: '',
// Unit test: (400, 100) -------<<
// Android: (171, 117) -------<<
// Chrome: (170, 117)
var painter = _getPainter(text, style);
print(painter.size);
// fontFamily: 'myDefaultFont',
// Unit test: (175, 120) -------<<
// Android: (175, 117)
// Chrome: (175, 117)
final painterCustom = _getPainter(textCustom, styleCustom);
print(painterCustom.size);
return Column(
children: [
text,
Text(painter.size.toString()),
textCustom,
Text(painterCustom.size.toString()),
],
);
})),
),
),
);
}
_getPainter(Text text, TextStyle style) {
final TextPainter painter = TextPainter(
text: TextSpan(children: [TextSpan(text: text.data!, style: style)]),
textDirection: text.textDirection ?? TextDirection.ltr,
maxLines: text.maxLines,
textScaleFactor: text.textScaleFactor ?? 1.0,
locale: text.locale,
textAlign: text.textAlign ?? TextAlign.start,
textHeightBehavior: text.textHeightBehavior,
textWidthBasis: text.textWidthBasis ?? TextWidthBasis.parent,
);
painter.layout();
return painter;
}
}
单元测试
- 注意:* 单元测试期望与
174.31640625
进行比较,表明结果未按应有的四舍五入?174.3
未通过单元测试。
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('paragraph', () async {
final Future<ByteData> data = rootBundle.load('assets/Roboto-Black.ttf');
final FontLoader fontLoader = FontLoader('myDefaultFont')..addFont(data);
await fontLoader.load();
const styleCustom = TextStyle(fontFamily: 'myDefaultFont', fontSize: 100);
const textCustom = Text('test', style: styleCustom);
const style = TextStyle(fontSize: 100);
const text = Text('test', style: style);
// ------------------------------------------------------
const constraints = ParagraphConstraints(width: 200);
final builderCustom = ParagraphBuilder(ParagraphStyle(
fontFamily: styleCustom.fontFamily, fontSize: styleCustom.fontSize));
builderCustom.addText(textCustom.data!);
final paragraphCustom = builderCustom.build();
paragraphCustom.layout(constraints);
final sizeCustom =
Size(paragraphCustom.longestLine, paragraphCustom.height);
// ------------------------------------------------------
final builder = ParagraphBuilder(ParagraphStyle(fontSize: style.fontSize));
builder.addText(text.data!);
final paragraph = builder.build();
paragraph.layout(constraints);
final size = Size(paragraph.longestLine, paragraph.height);
print(size);
print(sizeCustom);
expect(size, const Size(200, 200));
expect(sizeCustom, const Size(174.31640625, 120));
});
test('textpainter', () async {
final Future<ByteData> data = rootBundle.load('assets/Roboto-Black.ttf');
final FontLoader fontLoader = FontLoader('myDefaultFont')..addFont(data);
await fontLoader.load();
const style = TextStyle(fontSize: 100);
const text = Text('test', style: style);
const styleCustom = TextStyle(fontFamily: 'myDefaultFont', fontSize: 100);
const textCustom = Text('test', style: styleCustom);
var painter = _getPainter(text, style);
final painterCustom = _getPainter(textCustom, styleCustom);
print(painter.size);
print(painterCustom.size);
expect(painter.size, const Size(400, 100));
expect(painterCustom.size, const Size(175, 120));
});
}
_getPainter(Text text, TextStyle style) {
final TextPainter painter = TextPainter(
text: TextSpan(children: [TextSpan(text: text.data!, style: style)]),
textDirection: text.textDirection ?? TextDirection.ltr,
maxLines: text.maxLines,
textScaleFactor: text.textScaleFactor ?? 1.0,
locale: text.locale,
textAlign: text.textAlign ?? TextAlign.start,
textHeightBehavior: text.textHeightBehavior,
textWidthBasis: text.textWidthBasis ?? TextWidthBasis.parent,
);
painter.layout();
return painter;
}
问题
需要更改哪些参数才能使器械和单元测试的尺寸相同?
1条答案
按热度按时间yv5phkfx1#
结果表明,行高似乎是:
这解释了字体大小为100的Roboto的差异,它在Android上呈现的高度为117,但在单元测试中呈现的高度为120。
将行高设置为1.0将产生
Size(175,100)
。目前,这似乎是Roboto在(我的)Android移动的上的默认样式: