I am getting this error when trying to select a different value in DropDownButton. But not able to find the error.
Setting up the BLoC pattern is even easier with the dependency injection features of the Provider package and Streams from RXDart. Shared Preferences makes it possible to store and restore data to and from the bloc when state is lost.
In this video we'll demonstrate the usefulness of all three packages by creating a dynamic theme through BLoC that is seamlessly saved to and restored from the device on startup.
I have followed this example https://www.youtube.com/watch?v=ZpLQIFUqaGI
Main Class
void main() => runApp(Start ());
class Start extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
final String appTitle = "Opn same";
pageTitle(appTitle);
return ChangeNotifierProvider(
create: (BuildContext context) => PreferenceProvider(),
child: Consumer<PreferenceProvider>(
builder: (context, provider, child) {
return StreamBuilder<ThemeModel>(
stream: provider.bloc.customTheme,
builder: (context, snapshotCustomTheme) {
if (!snapshotCustomTheme.hasData) return Container();
return MaterialApp(
theme: snapshotCustomTheme.data!.customTheme,
title: appTitle,
initialRoute: "/Setting",
routes: routes,
);
});
},
),
);
}
}
Setting class:
class Setting extends StatefulWidget {
final String title;
Settings(this.title);
@override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
@override
Widget build(BuildContext context) {
final bloc = Provider.of<Preference>(context).bloc;
return Scaffold(
appBar: AppBar(
title: Text("Settings"),
leading: GestureDetector(
child: Icon(CupertinoIcons.back),
onTap: () {
bloc.savePreferences();
Navigator.of(context).pop();
},
)),
body: Center(
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Theme"),
StreamBuilder<ThemeModel>(
stream: bloc.customTheme,
builder: (context, snapshot) {
if (!snapshot.hasData) return Container();
return Container(
padding: EdgeInsets.all(20),
child: DropdownButton(
value: snapshot.data!.value,
items: [
DropdownMenuItem(
child: Text("Default"),
value: 1,
),
DropdownMenuItem(
child: Text("Drala"),
value: 2,
),
DropdownMenuItem(
child: Text("gold"),
value: 3,
)
],
onChanged: (int? value) {
print("value = $value");
setState(() {
bloc.changeTheme(bloc.inToTheme(value!)); **// Getting error here**
});
},
),
);
})
],
),
),
],
),
),
);
}
}
ThemeModel Class
class ThemeModel{
final ThemeData customTheme;
final int value;
ThemeModel ({ required this.customTheme, required this.value,});
}
preference bloc:
class PreferenceBloc {
final _customTheme = BehaviorSubject<ThemeModel>();
//Getters
Stream<Theodel> get customTheme => _customTheme.stream;
//Setters
Function(ThemeModel) get chanheme => _customTheme.sink.add;
indexToTheme(int value) {
return _customTheme.firstWhere((x) => x.value==value);
}
savePreferences() async {
SharedPreferences prefs = await Shareferences.getInstance();
await prefs.setInt('themeValue', _customTheme.value.value);
}
loadPreferences() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
int? themeValue = prefs.getInt('themeValue');
if (themeValue != null){
changeTheme(indeheme(themeValue));
} else {
changeTheme(ThemeModel(customTheme: ThemeData(
primaryColor: Color.fromRGBO(58, 66, 86, 1.0),
scaffoldBackgroundColor: Color.fromRGBO(247, 247, 247, 1.0),
brightness: Brightness.light,
visualDensity: VisualDensity(vertical: 0.5, horizontal: 0.5),
primaryColorBrightness: Brightness.light,
primaryTextTheme: TextTheme(
headline6: TextStyle(
fontWeight: FontWeight.w600,
fontFamily: "Raleway",
fontStyle: FontStyle.normal,
fontSize: 22.0,
letterSpacing: 1.6,
wordSpacing: 1.6,
color: Colors.white70,
),
),
),value: 2, ));
}
}
dispose() {
_customTheme.close();
}
}
class PreferenceProvider with ChangeNotifier {
late ThemePreferenceBloc _bloc;
ThemePreferenceProvider() {
_bloc = ThemePreferenceBloc();
_bloc.loadPreferences();
}
ThemeBloc get bloc => _bloc;
}
Error I am getting:
Performing hot restart...
Syncing files to device Android SDK built for x86...
Restarted application in 1,900ms.
I/zygote ( 6068): Do full code cache collection, code=120KB, data=83KB
I/zygote ( 6068): After code cache collection, code=111KB, data=66KB
I/flutter ( 6068): value = 3
E/flutter ( 6068): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type 'Future<ThemeModel>' is not a subtype of type 'ThemeModel'
E/flutter ( 6068): #0 _SettingsState.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:open_sesame/view/settings/settings.dart:65:55)
E/flutter ( 6068): #1 State.setState (package:flutter/src/widgets/framework.dart:1088:30)
E/flutter ( 6068): #2 _SettingsState.build.<anonymous closure>.<anonymous closure> (package:open_sesame/view/settings/settings.dart:64:31)
E/flutter ( 6068): #3 _DropdownButtonState._handleTap.<anonymous closure> (package:flutter/src/material/dropdown.dart:1266:25)
E/flutter ( 6068): #4 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter ( 6068): #5 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter ( 6068): <asynchronous suspension>
E/flutter ( 6068):
Please help.. Thanks in advance..