fromAssetMetadata static method

Widget fromAssetMetadata({
  1. Key? key,
  2. required String name,
  3. AssetBundle? bundle,
  4. String? package,
  5. EdgeInsetsGeometry? margin,
  6. EdgeInsetsGeometry? padding,
  7. Widget? child,
})

Create a new nine-patch image from a .9.json asset.

The bundle argument may be null, in which case the rootBundle is used.

The package argument must be non-null when fetching an asset that is included in a package.

Implementation

static Widget fromAssetMetadata({
  Key? key,
  required String name,
  AssetBundle? bundle,
  String? package,
  EdgeInsetsGeometry? margin,
  EdgeInsetsGeometry? padding,
  Widget? child,
}) {
  assert(name.endsWith('.9.json'),
      "We expect nine-patch metadata, which should end in '.9.json'.");

  final keyName = package == null ? name : 'packages/$package/$name';
  final metadataFile = (bundle ?? rootBundle).loadString(keyName);

  // We can't read the metadata asset synchronously, so we have to return a
  // FutureBuilder.
  return FutureBuilder(
    future: metadataFile,
    builder: (context, snapshot) {
      // handle errors
      if (snapshot.hasError) {
        return _debugBuildErrorWidget(context,
            'Error loading metadata for $keyName: ${snapshot.error}');
      }

      if (!snapshot.hasData) {
        // TODO Some kind of loading widget. What does Image do?
        return const Placeholder();
      }

      final metadata =
          common.NinePatchMetadata.fromJson(json.decode(snapshot.data!));

      if (metadata.name == null) {
        // TODO We could just guess the name.
        return _debugBuildErrorWidget(context,
            'Missing nine-patch image name in metadata for $keyName');
      }

      // Assume the image is in the same directory as the metadata.
      final p = path.Context(style: path.Style.posix);
      final imageName = p.join(p.dirname(keyName), metadata.name);

      return NinePatchImage(
        key: key,
        image: AssetImage(imageName),
        metadata: NinePatchMetadata.from(metadata),
        margin: margin,
        padding: padding,
        child: child,
      );
    },
  );
}