0

我在 module 中定义了一个自定义字体theme。该模块是模块中的一个依赖项widgets

小部件模块中的小部件应用自定义字体,如下所示

style: TextStyle(
  fontSize: fontSize,
  fontFamily: "IconActions",
  package: "theme"
)

它工作正常。

不幸的是,这种自定义字体没有呈现在金色图像上。我必须删除package: "theme"来解决这个问题。但这会破坏应用程序并且不再显示字体。所以基本上我可以让字体在生产代码或测试代码中正常工作,但不能同时使用。

setUp自定义字体在测试方法中加载

final fontData = File('assets/fonts/IconActions.ttf')
  .readAsBytes()
  .then((bytes) => ByteData.view(Uint8List.fromList(bytes).buffer));
final fontLoader = FontLoader('IconActions')..addFont(fontData);
await fontLoader.load();

我错过了什么,还是一个错误?

4

2 回答 2

1

所以基本上解决方案是package: "theme"从 TextStyle 中删除以使其工作。但这是解决方案的一半,因为正如我在问题中提到的,现在黄金文件具有正确的字体渲染器,但字体在应用程序中不起作用。

为了让它在应用程序中工作,我们需要给定项目结构:

pubspec.yaml(模块theme

flutter:
  fonts:
   - family 'ComicSans'
     fonts:
     - asset: packages/theme/fonts/ComicSans.ttf

小部件.dart(模块theme

style: TextStyle(
  fontSize: fontSize,
  fontFamily: "ComicSans",
)

现在在 modulewidgets中,这是包含您运行main.dartmain功能的模块,您必须再次定义字体:

pubspec.yaml(模块widgets

dependencies:
  flutter:
    sdk: flutter
  theme:
    path: ../path/to/theme/module

flutter:
  fonts:
   - family 'ComicSans'
     fonts:
     - asset: packages/theme/fonts/ComicSans.ttf

现在字体在应用程序和金色图像中都正确显示。

于 2020-03-31T05:24:49.360 回答
0

去年我遇到了这个确切的问题,也无法让字体加载在测试中工作。不知道这是具体的package论点,所以感谢您更新该结果。

至于另一种解决方法,有一种方法可以两全其美,您可以拥有独立的字体包,而不必在使用它的应用程序中声明打包的字体文件。

例如,我们有一个公司品牌/排版包,我们在多个应用程序中使用它,其中包含我们所有预配置的TextStyle声明,另一个独立包具有自定义生成IconData并存储在*.ttf文件中(如 FontAwesome)。

包装面:

发布规范.yaml


flutter:
  uses-material-design: true
  assets:
    - assets/fonts/
  fonts:
    - family: MyFont
      fonts:
        - asset: assets/fonts/MyFont.ttf
          weight: 400

    # etc

包装好的TextStyle

class BrandStyles {
  static const _packageName = '<package_name>';

  static const headline1Style = TextStyle(
    color: Colors.black,
    fontFamily: 'MyFont',
    fontSize: 60.0,
    fontStyle: FontStyle.normal,
    fontWeight: FontWeight.w400,
    height: 1.16,
    letterSpacing: 0,
    package: _packageName,
  );


  // etc

}

黄金测试

void main() {
  final widget = MaterialApp(
    theme: ThemeData(
      textTheme: TextTheme(
        // use custom extension method to remove `package` value
        headline1: BrandStyles.headline1Style.trimFontPackage(),
      ),
    ),
    home: Scaffold(
      body: SafeArea(child: StylesExample()),
    ),
  );

  setUp(() async {
    TestWidgetsFlutterBinding.ensureInitialized();
    final file = File('path/to/packaged/asset/MyFont.ttf').readAsBytesSync();
    final bytes = Future<ByteData>.value(file.buffer.asByteData());

    await (FontLoader('MyFont')..addFont(bytes)).load();
  });

  testWidgets('Golden typography test', (WidgetTester tester) async {
    await tester.pumpWidget(widget);
    await expectLater(
        find.byType(MaterialApp), matchesGoldenFile('goldens/typography.png'));
  });
}

extension StylingExtensions on TextStyle {
  
  TextStyle trimFontPackage() {
    return TextStyle(
      inherit: inherit,
      color: color,
      backgroundColor: backgroundColor,
      fontSize: fontSize,
      fontWeight: fontWeight,
      fontStyle: fontStyle,
      letterSpacing: letterSpacing,
      wordSpacing: wordSpacing,
      textBaseline: textBaseline,
      height: height,
      locale: locale,
      foreground: foreground,
      background: background,
      shadows: shadows,
      fontFeatures: fontFeatures,
      decoration: decoration,
      decorationColor: decorationColor,
      decorationStyle: decorationStyle,
      decorationThickness: decorationThickness,
      debugLabel: debugLabel,
      /// `replaceAll` only required if loading multiple fonts, 
      /// otherwise set value to your single `fontFamily` name
      fontFamily: fontFamily.replaceAll('packages/<package_name>/', ''),
    );
  }
}

或者,如果像我一样,您对自定义图标有同样的问题,可以在您的自定义图标的黄金测试中IconData使用类似的扩展方法完成相同的操作,删除该fontPackage值:

extension IconExtensions on IconData {
  IconData convertToGolden() => IconData(
        this.codePoint,
        fontFamily: this.fontFamily,
      );
}

你的应用端

发布规范.yaml


# ...

dependencies:
  flutter:
    sdk: flutter

  <package_name>:
    git:
      url: <url_to_hosted_package>.git
      ref: <release_tag>

主要.dart


class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData.light().copyWith(
        textTheme: TextTheme(
          headline1: BrandStyles.headline1Style,
        ),
      ),
    );
  }

}

现在不再需要在您的应用程序中声明您的字体pubspec.yaml,甚至不需要在与您的实施应用程序相同的项目/存储库中拥有样式包。

于 2021-02-24T04:55:20.887 回答