Issue
i’ve a problem with "nullable expression". The problem is in theese two lines: left: isSideBarOpenedAsync.data ? 0 : 0,
and right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35,
i’m trying to open with an animation the sidebar menu. Some idea to fix that? Ty.
This is the error: Error: A value of type ‘bool?’ can’t be assigned to a variable of type ‘bool’ because ‘bool?’ is nullable and ‘bool’ isn’t.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:solaris/constants.dart';
import 'package:rxdart/rxdart.dart';
class SideBar extends StatefulWidget {
@override
_SideBarState createState() => _SideBarState();
}
class _SideBarState extends State<SideBar> with SingleTickerProviderStateMixin<SideBar>{
late AnimationController _animationController;
late StreamController<bool> isSidebarOpenedStreamController;
late Stream<bool> isSideBarOpenedStream;
late StreamSink<bool> isSideBarOpenedSink;
final _animationDuration = const Duration(milliseconds: 500);
@override
void initState(){
super.initState();
_animationController = AnimationController(vsync: this, duration: _animationDuration);
isSidebarOpenedStreamController = PublishSubject<bool>();
isSideBarOpenedStream = isSidebarOpenedStreamController.stream;
isSideBarOpenedSink = isSidebarOpenedStreamController.sink;
}
@override
void dispose(){
_animationController.dispose();
isSidebarOpenedStreamController.close();
isSideBarOpenedSink.close();
super.dispose();
}
void onIconPressed(){
final animationStatus = _animationController.status;
final isAnimationCompleted = animationStatus == AnimationStatus.completed;
if(isAnimationCompleted){
isSideBarOpenedSink.add(false);
_animationController.reverse();
}else{
isSideBarOpenedSink.add(true);
_animationController.forward();
}
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return StreamBuilder<bool>(
initialData: false,
stream: isSideBarOpenedStream,
builder: (context, isSideBarOpenedAsync){
return AnimatedPositioned(
duration: _animationDuration,
top: 0,
bottom: 0,
left: isSideBarOpenedAsync.data ? 0 : 0,
right: isSideBarOpenedAsync.data ? 0 : screenWidth - 35,
child: Row(
children: <Widget>[
Expanded(
child: Container(
color: red,
),
),
Align(
alignment: Alignment(0,-0.9),
child: GestureDetector(
onTap: (){
onIconPressed();
},
child: Container(
width: 35,
height: 110,
color: blue,
alignment: Alignment.centerLeft,
child: AnimatedIcon(
progress: _animationController.view,
icon: AnimatedIcons.menu_close,
color: white,
size: 25,
),
),
),
),
],
),
);
},
);
}
}
Solution
if you know that isSideBarOpenedAsync.data
will always have data, you can use a !
to force the value to not be null.
for example:
isSideBarOpenedAsync.data!
. This changes the value from bool?
to bool
. Your ternary expressions will work with this logic.
Note: if isSideBarOpenedAsync.data
is in fact null and you have !
, then you will get an error saying that bool cannot be type null
.
if you don’t want this behavior, you can also provide a default value.
for example:
(isSideBarOpenedAsync.data ?? false)
In this case, if isSideBarOpenedAsync.data
has a value, it will be referenced. If it is null, false
will be used instead.
Answered By – mrgnhnt96
Answer Checked By – Marilyn (FlutterFixes Volunteer)