I am the beginner of Flutter. Recently stuck in creating widget.
Here is my condition. I use SharedPreferences
getting Boolean value at first then create widget. However, my widget always show in TRUE condition, even though the Boolean value is false. In my widget, there is a GestureDetector
with onTap()
. My widget will change to right status after I tap in it. But I wish it should be the right status while initial creation. Thus, I am really confused about that. I appreciate your help very much.
SharedPreferences
For getting data.
String id = "";
Future _UIsetting() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
flip=prefs.getBool('flip')!;
id=prefs.getString("ID").toString();
}
Widget build
@override
Widget build(BuildContext context) {
_UIsetting(); //getting data
return Container(
child:Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
**//something wrong here. Nothing show at first**
Text("HI $id"),
Container(
color: sliver,
child: GestureDetector(
onTap: (){
setState(() {
_flipCheck();
});
},
child: AnimatedSwitcher(
duration: Duration(seconds: 1),
transitionBuilder: (Widget widget, Animation<double> animation){
final rotateAnim = Tween(begin: pi, end: 0.0).animate(animation);
return AnimatedBuilder(
animation: rotateAnim,
child: widget,
builder: (context, widget) {
final isUnder = (ValueKey(flip) != widget);
final value = isUnder ? min(rotateAnim.value, pi / 2) : rotateAnim.value;
return Transform(
transform: Matrix4.rotationY(value),
child: widget,
alignment: Alignment.center,
);
},
);
},
**//something wrong here. Showing TRUE condition at first(Not the right status).**
child: flip?
SizedBox(
key: ValueKey(0),
width: MediaQuery.of(context).size.width,
height: 250,
child: Image.asset('assets/work1.png'),
):
SizedBox(
key: ValueKey(1),
width: MediaQuery.of(context).size.width,
height: 250,
child: Image.asset('assets/work2.png'),
),
)
)
),
**//something wrong here. Showing TRUE condition at first(Not the right status).**
flip?Text("TRUE Condition"):Text("FALSE Condition"),
],
)
);}
_flipCheck()
checking flip picture or not
Future _flipCheck() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
previous=prefs.getInt('previous_timestamp')!;
flip=prefs.getBool('flip')!;
int now=DateTime.now().millisecondsSinceEpoch;
if((now-previous)~/3600000>=8){
//update time
prefs.setInt('previous_timestamp', now) ;
flip=true;
prefs.setBool('flip', true);
}else{
flip=false;
prefs.setBool('flip', false);
}
}
All code is in class myAPPState extends State<myAPP>{}
2
Answers
It seems like you’re facing an issue where the initial state of flip is not reflected in your widget. This could be due to the asynchronous nature of SharedPreferences.getInstance().
One approach to handle this is to use a FutureBuilder to wait for the result of SharedPreferences.getInstance() before building the widget tree. Here’s how you can modify your code:
This modification ensures that _UIsetting() is called before the widget tree is built, which should resolve the issue with the initial state of flip.
Another option would be to use run method after screen construction has finished.
https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html
But @Hasib Akon answer with FutureBuilder is better if it applies to you.