试图在颤振中做颜色选择器

时间:2021-03-17 11:05:51

标签: flutter dart sharedpreferences flutter-provider

我正在尝试为我的应用程序制作一个颜色选择器...

我从 pub dev 安装了 Mtaerial Color Picker 包...

然后我尝试像我为我的黑暗模式所做的那样制作一个提供者......

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;
}

swapTheme() 用于我的暗模式和更改颜色对于我的问题,我从我的选择器中获取 Color int 如下:

  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);
          });
         },
        ),

当我选择一种颜色时,它只会激活更改颜色功能,它应该重建我的应用程序,因为我在 main.dart 中使用了提供程序,这就是我的暗模式的工作方式

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,

它给了我这个错误

<块引用>

方法 '&' 在 null 上被调用。

<块引用>

接收者:null 尝试调用:

<块引用>

&(4294967295)

还有这个

<块引用>

错误状态:试图读取在创建其值期间抛出的提供程序。

<块引用>

创建类型 ThemeProvider 时发生异常。

1 个答案:

答案 0 :(得分:0)

好的,所以应该这样做,这是我的黑暗模式更换器主题之一:

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;
}

我的换色器文件:

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;
}

我更改两者的地方是我的设置页面,您将小部件放在任何页面中...

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,
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

这里我使用了共享首选项..所以我可以看到我的开关按钮与共享首选项一起工作

以及如何在主 dart 的 Themedata 中使用 both 提供程序:

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(),
        },
      );
    });
  }
}

我想我在我的应用程序中使用它很有帮助..

谢谢你们..