trying to do color picker in flutter

Issue

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.

Solution

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

Answered By – Yusof Antar

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *