はじめに
Flutterの独自Pluginを開発中に、
通常のアプリ開発同様画像を表示しようとしたところ
表題のエラーでちょっと困ったので書いておきます。
問題のコード
下記 SampleWidget
はPlugin内に実装した画像を表示するためのシンプルなWidgetてす。
をexample app(※1)て実行すると Unable to load asset: assets/images/sample.png
エラーにより、画像表示に失敗します。
class SampleWidget extends StatelessWidget {
const ExampleWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Image(
image: AssetImage(
'assets/images/sample',
),
);
}
}
(※1)
example appはPlugin作成時にデフォルトで用意される確認,検証用のAppです。
exampleフォルダ以下に生成されます。
確認したこと
画像の表示に失敗するケースとして、
- そもそもassetのバスを間違えている
- pubspec.ymlの内容が間違っている
などありますが、どれも該当しませんでした。
解消した方法
下記のように、AssetImage classのコンストラクタ引数 package
に
class ExampleWidget extends StatelessWidget {
const ExampleWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Image(
image: AssetImage(
'assets/images/example.png',
package: 'package_name'
),
);
}
}
自身のPlugin名を指定することで、無事表示に成功しました。
なぜ画像が表示できなかったのか
ドキュメントによると、外部Package(広義のPackage)からAssetを参照する場合はpackage名を指定することが必須になっています
To fetch an asset from a package, the package argument must be provided.
自身のパッケージ内にAssetがある場合は指定の必要がありません。
しかし今回の用にPlugin側が画像を保持している場合は、
呼び出し側は該当Pluginの画像を保持していないため、
画像の取得先を指定する必要がありました。
都度パッケージ名を書く手間を省く
下記のように、 常にPackage名を指定するクラスを用意するのも良いかもしれません
class SampleAssetImage extends AssetImage {
const SampleAssetImage(String assetName) : super(assetName, package: 'sample');
}