Reputation: 309
I was trying to do a Color Picker for my app in flutter...
i installed the Mtaerial Color Picker package from pub dev...
then i tried to make a Provider like i made for my Dark Mode...
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ThemeProvider with ChangeNotifier {
ThemeData _selectedTheme;
int primaryValue;
static Color secondaryColor;
ThemeProvider({
bool isDarkMode,
int primaryValue,
}) {
this._selectedTheme = isDarkMode ? dark : light;
this.primaryValue = colorValue;
}
static int colorValue;
ThemeData light = ThemeData.light().copyWith(
primaryColor: Color(colorValue) ?? Colors.teal[700],
);
ThemeData dark = ThemeData.dark().copyWith();
void changeColor(int value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
colorValue = value;
primaryValue = colorValue;
print(colorValue);
prefs.setInt('PrimaryColor', primaryValue);
notifyListeners();
}
void swapTheme() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (_selectedTheme == dark) {
_selectedTheme = light;
prefs.setBool('isDarkTheme', false);
print(prefs.getBool('isDarkTheme'));
} else {
_selectedTheme = dark;
prefs.setBool('isDarkTheme', true);
print(prefs.getBool('isDarkTheme'));
}
notifyListeners();
}
ThemeData get getTheme => _selectedTheme;
}
the swapTheme() is for my dark Mode and the change Color it is For my problem i get the Color int from my picker like that:
MaterialColorPicker(
circleSize: 50,
selectedColor:
_selectedColor ?? Colors.teal[700],
onColorChange: (Color color) {
setState(() {
_selectedColor = color;
String primaryColorString =
_selectedColor.toString();
String valueString = primaryColorString
.split('(0x')[1]
.split(')')[0];
int value =
int.parse(valueString, radix: 16);
themeProvider.changeColor(value);
});
},
),
and when i choose a color it just activate the change color function where it should rebuild my app because i am using provider in my main.dart thats how my Dark Mode is working
return runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (BuildContext context) => ThemeProvider(
isDarkMode: prefs.getBool('isDarkTheme') ?? false,
primaryValue: prefs.getInt('PrimaryColor') ?? 4293467747,
),
),
],
child: MyApp(),
),
);
}
return Consumer<ThemeProvider>(
builder: (context, themeProvider, _) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: themeProvider.getTheme,
tho its giving me This Error
The method '&' was called on null.
Receiver: null Tried calling:
&(4294967295)
and this too
Bad state: Tried to read a provider that threw during the creation of its value.
The exception occurred during the creation of type ThemeProvider.
Upvotes: 1
Views: 2034
Reputation: 309
okay so it should be done this way this is my darkMode changer the theme one :
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class DarkModeProvider with ChangeNotifier {
ThemeData _selectedTheme;
DarkModeProvider({
bool isDarkMode,
}) {
this._selectedTheme = isDarkMode ? dark : light;
}
ThemeData light = ThemeData.light();
ThemeData dark = ThemeData.dark();
void swapDarkMode() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (_selectedTheme == dark) {
_selectedTheme = light;
prefs.setBool('isDarkMode', false);
} else {
_selectedTheme = dark;
prefs.setBool('isDarkMode', true);
}
notifyListeners();
}
ThemeData get getTheme => _selectedTheme;
}
my color changer file:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ColorChanger with ChangeNotifier {
int primary;
int secondary;
ColorChanger({
this.primary,
this.secondary,
});
void changePrimaryColor(int prim) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
primary = prim;
prefs.setInt('Primary', primary);
notifyListeners();
}
void changeSecondaryColor(int second) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
secondary = second;
prefs.setInt('Secondary', secondary);
notifyListeners();
}
int get getPrimColor => primary;
int get getSecondColor => secondary;
}
where i change both is my setting page you put the widgets in any page...
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
import '../providers/color_provider.dart';
import '../providers/dark_mode_provider.dart';
class SettingsScreen extends StatefulWidget {
static const routeName = '/settings';
@override
_SettingsScreenState createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
bool _darkValue = false;
Color _selectedPrimaryColor;
Color _selectedSecondaryColor;
_onBackPressed() {
Navigator.of(context).pushReplacementNamed('/home');
}
getSharedPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var value = prefs.getBool('isDarkMode') ?? false;
if (value == false) {
setState(() {
_darkValue = false;
});
} else {
setState(() {
_darkValue = true;
});
}
}
@override
void initState() {
super.initState();
getSharedPrefs();
}
@override
Widget build(BuildContext context) {
DarkModeProvider darkModeProvider = Provider.of<DarkModeProvider>(
context,
listen: false,
);
ColorChanger colorChanger = Provider.of<ColorChanger>(
context,
listen: false,
);
return WillPopScope(
onWillPop: () {
return _onBackPressed();
},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
_onBackPressed();
},
),
),
body: Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
child: Text(
'Dark Mode',
style: TextStyle(
fontSize: 20,
),
),
),
),
Switch(
value: _darkValue,
onChanged: (toggle) {
darkModeProvider.swapDarkMode();
getSharedPrefs();
}),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
child: Text(
'Primary Colors',
style: TextStyle(
fontSize: 20,
),
),
),
),
TextButton(
onPressed: () {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
actions: <Widget>[
IconButton(
onPressed: () {
Navigator.of(context).pop(true);
},
icon: Icon(Icons.check),
),
],
content: SingleChildScrollView(
child: Container(
height:
MediaQuery.of(context).size.height * 0.35,
child: MaterialColorPicker(
circleSize: 50,
selectedColor:
Color(colorChanger.getPrimColor) ??
Colors.teal[700],
onColorChange: (Color color) {
setState(() {
_selectedPrimaryColor = color;
colorChanger.changePrimaryColor(
_selectedPrimaryColor.value);
});
},
),
),
),
);
},
);
},
child: CircleAvatar(
child: Icon(
Icons.color_lens,
color: Colors.white54,
),
backgroundColor:
Color(colorChanger.getPrimColor) ?? Colors.teal[700],
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
child: Text(
'Secondary Colors',
style: TextStyle(
fontSize: 20,
),
),
),
),
TextButton(
onPressed: () {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
actions: <Widget>[
IconButton(
onPressed: () {
Navigator.of(context).pop(true);
},
icon: Icon(Icons.check),
),
],
content: SingleChildScrollView(
child: Container(
height:
MediaQuery.of(context).size.height * 0.35,
child: MaterialColorPicker(
circleSize: 50,
selectedColor:
Color(colorChanger.getSecondColor) ??
Colors.amber,
onColorChange: (Color color) {
setState(() {
_selectedSecondaryColor = color;
colorChanger.changeSecondaryColor(
_selectedSecondaryColor.value);
});
},
),
),
),
);
},
);
},
child: CircleAvatar(
child: Icon(
Icons.color_lens,
color: Colors.white54,
),
backgroundColor:
Color(colorChanger.getSecondColor) ?? Colors.amber,
),
),
],
),
],
),
),
),
);
}
}
here i used shared prefs.. so i can see my switch button functioning with the shared prefs
and here how you can use the both provider in the Themedata in the main dart:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todo/providers/task_provider.dart';
import 'package:todo/screens/add_task_screen.dart';
import './screens/settings_screen.dart';
import './providers/color_provider.dart';
import './providers/dark_mode_provider.dart';
import './screens/home_screen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences prefs = await SharedPreferences.getInstance();
return runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (BuildContext context) => TaskProvider(),
),
ChangeNotifierProvider(
create: (BuildContext context) => DarkModeProvider(
isDarkMode: prefs.getBool('isDarkTheme') ?? false,
),
),
ChangeNotifierProvider(
create: (BuildContext context) => ColorChanger(
primary: prefs.getInt('Primary') ?? Colors.teal[700].value,
secondary: prefs.getInt('Secondary') ?? Colors.amber.value,
),
),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return Consumer2<DarkModeProvider, ColorChanger>(
builder: (context, darkmode, colorChanger, _) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: darkmode.getTheme.copyWith(
primaryColor: Color(colorChanger.getPrimColor),
accentColor: Color(colorChanger.getSecondColor),
),
home: HomeScreen(),
routes: {
HomeScreen.routeName: (context) => HomeScreen(),
SettingsScreen.routeName: (context) => SettingsScreen(),
AddTaskScreen.routeNamed: (context) => AddTaskScreen(),
},
);
});
}
}
i guess its helpful i used it in my app..
thank you guys..
Upvotes: 1