'The element type FutureBuilder can't be assigned to type

I'm using the settings_ui package.

I'm making an app that primary will be used on Android but also iOS. In the settings screen I want to display the web view version.

My settings are made using the settings_ui package, and the app consists of a web view, using this package.

A method exists to return the web view version Android is using. To retrieve this, we need to make use of await.

I want to dynamically add a section to my list of settings if the device is Android. That part is simple.

The problem is I can't work out how to read the async value inside what I think I need, a FutureBuilder.

The settings_ui expects an array of List sections.

For example:

   return SettingsList(
  sections: [
    SettingsSection(
      title: const Text('Common'),
      tiles: [
        SettingsTile(
          title: const Text('Web address'),
          description: const Text('Change the web address.'),
          leading: const Icon(Icons.language),
          onPressed: (context) {
            Navigator.push(
              context,
              MaterialPageRoute(fullscreenDialog: true, builder: (context) => const WebAddressForm()),
            );
          },
        ),...

I then have code if the device is Android (simplified for demonstration purposes):

       if (showAndroidSection)
      FutureBuilder<SettingsSection>(
          future: _someFutureToGetAndroidWebViewVersion(), builder: (context, snapshot) => SettingsSection(tiles: []))

Doing this gives me the error "The element type 'FutureBuilder' can't be assigned to the list type 'AbstractSettingsSection'". I have tried casting to no avail.

I am aware I shouldn't be calling the future in the build method - and I will move to initState but the problem will still remain. How do I return the web view version within a dynamic SettingsSection?

I hope that makes sense. Thanks.

The way I'm working around this currently is the following, but feels wrong to me...

  late String _versionName = "";



  @override
  void initState() {
    super.initState();
    enableCustomChromeTabs = SharedPrefs.instance.getBool(Settings.customChromeTabs) ?? false;
    if (!kIsWeb && Platform.isAndroid) {
      showAndroidSection = true;
      getPackageInfo().then((value) {
        setState(() {
          _versionName = value!.versionName ?? "Unable to retrieve.";
        });
      });
    }

Then later...

       SettingsSection(
      title: const Text(_versionName),
      tiles: [
        SettingsTile.switchTile(
          title: const Text('xyz'),
      ...


Solution 1:[1]

I solved it as follows (unsure if this is the correct way or an "easier" way):

Added this to the array of sections:

MyWidget()

and...

class MyWidget extends AbstractSettingsSection {
  @override
  Widget build(context) {
    return FutureBuilder<AndroidWebViewPackageInfo?>(
        future: getPackageInfo(),
        builder: (context, AsyncSnapshot<AndroidWebViewPackageInfo?> snapshot) {
          return SettingsSection(
            title: const Text("Android debugging"),
            tiles: [
              CustomSettingsTile(
                child: Container(
                  padding: const EdgeInsetsDirectional.only(
                    start: 25,
                  ),
                  child: Text(
                    snapshot.data,
                  ),
                ),
              ),
            ],
          );
        });
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ricky