Issue
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..
Solution
The reason I was not able to get it working was I was not able to access the data stored in another file. So now I brought the data into the same file.
import 'package:flutter/material.dart';
import 'package:rxdart/subjects.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:testing/models/color.dart';
class PreferenceBloc{
final _brightness = BehaviorSubject<Brightness>();
final _primaryColor = BehaviorSubject<ColorModel>();
final _colors = [
ColorModel(color: Colors.blue,index: 0.0, name: 'Blue'),
ColorModel(color: Colors.green,index: 1.0, name: 'Green'),
ColorModel(color: Colors.red,index: 2.0, name: 'Red'),
ColorModel(color: Colors.white,index: 3.0, name: 'White'),
];
//Getters
Stream<Brightness> get brightness => _brightness.stream;
Stream<ColorModel> get primaryColor => _primaryColor.stream;
//Setters
Function(Brightness) get changeBrightness => _brightness.sink.add;
Function(ColorModel) get changePrimaryColor => _primaryColor.sink.add;
indexToPrimaryColor(double index){
return _colors.firstWhere((x) => x.index==index);
}
savePreferences() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (_brightness.value == Brightness.light){
await prefs.setBool('dark', false);
} else {
await prefs.setBool('dark', true);
}
await prefs.setDouble('colorIndex', _primaryColor.value.index);
}
loadPreferences() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool? darkMode=prefs.getBool('dark');
double? colorIndex = prefs.getDouble('colorIndex');
if (darkMode != null){
(darkMode == false) ? changeBrightness(Brightness.light) : changeBrightness(Brightness.dark);
} else {
changeBrightness(Brightness.light);
}
if (colorIndex != null){
changePrimaryColor(indexToPrimaryColor(colorIndex));
} else {
changePrimaryColor(ColorModel(color: Colors.blue,index: 0.0, name: 'Blue'));
}
}
dispose(){
_primaryColor.close();
_brightness.close();
}
}
Answered By - GOKU
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.