flutter / website

Flutter documentation web site
https://docs.flutter.dev
Other
2.81k stars 3.21k forks source link

Bundling package assets is not described the way it works #11284

Open Gustl22 opened 2 days ago

Gustl22 commented 2 days ago

Page URL

https://docs.flutter.dev/ui/assets/assets-and-images/

Page source

https://github.com/flutter/website/tree/main/src/content/ui/assets/assets-and-images.md

Describe the problem

If I create a package and want to include and use assets explicitely in that package, I cannot use them as described:

flutter create asset_example_package --template=package
cd asset_example_package
mkdir -p assets && echo "Hello World" > assets/my_asset.txt
# Create an app to test the package
flutter create example 

This is what I expect to load an asset in a package itself:

// lib/asset_example_package.dart

library asset_example_package;
import 'package:flutter/services.dart';
class AssetTestClazz {
  Future<String> getAssetStr() async {
    return await rootBundle.loadString('assets/my_asset.txt');
  }
}

Add these lines to the pubspec.yaml of the package:

flutter:
  assets:
    - assets/my_asset.txt

Replace the MyHomePage widget in the example/lib/main.dart with:

FutureBuilder(future: AssetTestClazz().getAssetStr(), builder: (context, snapshot) => Text(snapshot.data ?? 'not loaded yet'),)

Execute the example/main.dart

Expected fix

The docs state this: https://docs.flutter.dev/ui/assets/assets-and-images#bundling-of-package-assets

If the desired asset is specified in the pubspec.yaml file of the package, it's bundled automatically with the application. In particular, assets used by the package itself must be specified in its pubspec.yaml.

A package can also...

~Which is actually not applicable: the assets cannot be defined in the root of the package, as they cannot be accessed by the package itself, besides for testing. They must always be included in the lib directory. So it's not automatically bundled with the application, even if specified in the pubspec.yaml. So this section should be removed.~ Edit: this actually works by using the prefix of packages/my-package. See below comment. It's just not clear that this approach must be used for both approaches.

~If I missed how they can be included inside a package, there should be also stated how this could be done (not from within the app facing package).~

Additional context

~Exuting the above example also on web doesn't show the asset in the package directory within the browser tools.~ Edit: I cannot see the resource, but obviously its loading non the less.

Related: https://github.com/flutter/flutter/issues/65921 https://github.com/flutter/flutter/issues/111400

I would like to fix this problem.

Gustl22 commented 2 days ago

Actually it worked by using within the package itself

    return await rootBundle.loadString('packages/asset_example_package/assets/my_asset.txt');

which is also decribed below in the docs:

To load the image within your package, use: return const AssetImage('packages/fancy_backgrounds/backgrounds/background1.png');

But this was not clear to me, that this approach also applies for the direct approach (without using lib). So regardless, of using lib or placing it in the root, it's the same path.

You can close if this is not a reason to adapt the docs.