'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 |
