I added sharedpreferences to checkbox then shows " " error and "[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value" error on flutter. How I resolve it?
checkbox flutter code
class ConstantScreen2 extends StatefulWidget {
const ConstantScreen2({Key? key}) : super(key: key);
@override
State<ConstantScreen2> createState() => _ConstantScreen2State();
}
class _ConstantScreen2State extends State<ConstantScreen2> {
final _preferencesService = PreferencesService();
var isChecked = false;
@override
void initState() {
super.initState();
_populateFields();
}
void _populateFields() async {
final settings = await _preferencesService.getSettings();
setState(() {
isChecked = settings.isChecked!;
});
}
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
return Scaffold(
backgroundColor: Colors.white,
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(Config.app_background3), fit: BoxFit.cover),
),
child: SafeArea(
child: ListView(
padding:
const EdgeInsets.only(top: 0, bottom: 0, right: 5, left: 0),
children: <Widget>[
Row(
children: <Widget>[
const Expanded(
child: ListTile(
minLeadingWidth: 1,
leading: Icon(
Icons.brightness_1,
color: Colors.black,
size: 10.0,
),
title: Text(
Config.app_agree2,
style: TextStyle(
fontSize: 13, fontWeight: FontWeight.bold),
),
),
),
const Text(
'yes',
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
side: MaterialStateBorderSide.resolveWith(
(states) =>
BorderSide(width: 3.0, color: Colors.blueAccent),
),
value: isChecked,
onChanged: (value) => setState(() => isChecked = value!),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 10, left: 0, bottom: 0),
child: Center(
child: SizedBox(
width: 160.0,
height: 35.0,
child: ElevatedButton(
style: ButtonStyle(
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: const BorderSide(
color: Colors.blueAccent,
),
),
),
),
onPressed: isChecked ? displayMessage : null,
child: const Text('next'),
),
),
),
),
],
),
),
),
);
}
void displayMessage() {
if (isChecked == true) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ChildGrowScreen()),
);
_saveSettings;
} else {}
}
void _saveSettings() {
final newSettings = Settings(isChecked: isChecked);
print(newSettings);
_preferencesService.saveSettings(newSettings);
}
}
model
class Settings {
bool? isChecked;
Settings({bool? isChecked});
}
preference_services page
import 'package:shared_preferences/shared_preferences.dart';
import 'constant2_model.dart';
class PreferencesService {
Future saveSettings(Settings settings) async {
final preferences = await SharedPreferences.getInstance();
await preferences.setBool('isChecked', settings.isChecked!);
print('Saved settings');
}
Future<Settings> getSettings() async {
final preferences = await SharedPreferences.getInstance();
final isChecked = preferences.getBool('isChecked');
return Settings(isChecked: isChecked);
}
}
I can't understand my error. How I resolve it? In my code I used a separate model and to save data I used the preference_service file.
CodePudding user response:
The error is self-explaining: you're using a null-check operator (the !
) on a variable that can be null
, and the error is thrown because at runtime that variable is null
indeed.
The !
tells your program that, despite being of a nullable type (because of the ?
after its type), you're sure that at runtime it will never become null
...but that happens to be a lie, so flutter throws the error.
I suggest some debugging to discover why that variable becomes null
, especially in any line of code where you're using !
.
EDIT
Either here isChecked
is null
void _populateFields() async {
final settings = await _preferencesService.getSettings();
setState(() {
isChecked = settings.isChecked!;
});
}
or here value
is null
value: isChecked,
onChanged: (value) => setState(() => isChecked = value!),
or here isChecked
again is null
await preferences.setBool('isChecked', settings.isChecked!);
and that goes against your code, since for the compiler putting !
after a variable means "this variable will not be null
here" (I think I got all the !
in your code).
Hence the error: you have to check why value
or isChecked
are null
when they shouldn't be.
CodePudding user response:
In your ConstantScreen2
class inside _populateFields
change this:
if(settings.isChecked != null){
setState(() {
isChecked = settings.isChecked;
});
}
and in your check box do this:
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
side: MaterialStateBorderSide.resolveWith(
(states) =>
BorderSide(width: 3.0, color: Colors.blueAccent),
),
value: isChecked,
onChanged: (value) {
if(value != null){ // <---- add this
setState(() => isChecked = value)
}
},
),
and in your PreferencesService
inside saveSettings
change to this:
if(settings.isChecked != null){
final preferences = await SharedPreferences.getInstance();
await preferences.setBool('isChecked', settings.isChecked!);
}
For your last issue first you call function wrong, you need add ()
to _saveSettings
, second your PreferencesService's _saveSettings
is a future so you needed to await
so change your _saveSettings()
to future<void>
and await
to it then navigate to ChildGrowScreen
page. So change this:
void displayMessage() {
if (isChecked == true) {
await _saveSettings(); //<--- add this
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ChildGrowScreen()),
);
} else {}
}
and this:
Future<void> _saveSettings() {
final newSettings = Settings(isChecked: isChecked);
print(newSettings);
_preferencesService.saveSettings(newSettings);
}