问题描述
首先,我创建了一个设计好的底部工作表,其中有两个列表,借助CupertinoPicker
小部件来显示数字(左侧)和选项(小时,日,周,月),
数字将取决于我选择的选项,如果选择小时,则左侧数字应为1-24,如果选择星期,数字应为1-4,选择日期,则数字应为1。 1-30,最后我选择的月份号应该是1-12。
代码:
所有列表变量:
List<String> reminderDay = ['hour','day','week','month'];
List<String> reminderHoursVal =['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24'];
List<String> reminderDaysVal =['1','24','25','26','27','28','29','30','31'];
List<String> reminderMonthsVal =['1','12'];
List<String> reminderWeeksVal =['1','4'];
String selectedReminderVal='1';
String selectedReminderDay ='hour';
底页代码:
addReminder(){
showModalBottomSheet(
context: context,builder: (BuildContext context) {
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,duration: const Duration(milliseconds: 100),curve: Curves.decelerate,child: Container(
padding: const EdgeInsets.only(top:8,right: 8,left:8,bottom: 8),height: MediaQuery.of(context).size.height/2,// color: Colors.transparent,decoration: BoxDecoration(
color: Colors.white,borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),topRight: Radius.circular(30)
)
),child: Container(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [
SizedBox(height:10),Text("Set a reminder",style: TextStyle(
fontSize:18,fontWeight:FontWeight.bold,color: Colors.grey
),),SizedBox(height:20),Container(
margin: const EdgeInsets.only(left: 10,right: 10),height: MediaQuery.of(context).size.height/4,decoration: BoxDecoration(
color: Colors.grey[100],borderRadius: BorderRadius.circular(10)
),child: Row(
crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,itemExtent: 30,backgroundColor: Colors.grey[100],onSelectedItemChanged: (int val) {
setState(() {
if(selectedReminderDay=='day'){
selectedReminderVal = reminderDaysVal[val];
}else if(selectedReminderDay=='week'){
selectedReminderVal = reminderWeeksVal[val];
}else if(selectedReminderDay=='month'){
selectedReminderVal = reminderMonthsVal[val];
}else{
selectedReminderVal = reminderHoursVal[val];
}
print("selectedReminderVal:$selectedReminderVal");
});
},children:selectedReminderDay=='day'?reminderDaysVal
:selectedReminderDay=='week'?reminderWeeksVal
:selectedReminderDay=='month'?reminderMonthsVal:reminderHoursVal// ['hour','month']; reminderHoursVal
.map(
(item) => Center(
child: Text(
item,style: TextStyle(
fontSize: 16,// fontWeight:FontWeight.bold,)
.toList()),Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,onSelectedItemChanged: (int val) {
setState(() {
selectedReminderDay = reminderDay[val];
print("selectedReminderDay:$selectedReminderDay");
});
},children: reminderDay
.map(
(item) => Center(
child: Text(
item,])
),SizedBox(height:15),// selectedVal!=null?Text(selectedVal.toString()):Container()
Column(
mainAxisAlignment: MainAxisAlignment.center,children: [
Text("You'll get the reminder"),Text('$selectedReminderVal $selectedReminderDay before the event')
],SizedBox(height:25),Padding(
padding: const EdgeInsets.only(left: 10,child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
InkWell(
onTap: (){
Navigator.pop(context);
},child: Text("Cancel",style: TextStyle(
fontSize: 18,color: Colors.blue,fontWeight: FontWeight.bold
),InkWell(
onTap: (){
Navigator.pop(context);
},child: Container(
alignment: Alignment.center,decoration: BoxDecoration(
color: Colors.blue,borderRadius: BorderRadius.circular(8)
),width: MediaQuery.of(context).size.width/5,height: MediaQuery.of(context).size.height/25,child: Text("Save",style:TextStyle(
color: Colors.white,fontSize: 19
)),)
],)
],)
),);
},);
}
屏幕截图:
解决方法
这是因为您要设置的状态不同于模式底部工作表中的状态。
现在,当您调用setState时,实际上是在模态底部工作表下重建有状态的小部件。
要解决此问题,只需将底部工作表包裹在有状态的构建器中即可。
StatefulBuilder(
builder: (context,setState) {
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,duration: const Duration(milliseconds: 100),curve: Curves.decelerate,child: Container(
padding: const EdgeInsets.only(top:8,right: 8,left:8,bottom: 8),height: MediaQuery.of(context).size.height/2,// color: Colors.transparent,decoration: BoxDecoration(
color: Colors.white,....
,
当我们在现有状态下创建新的上下文小部件时,状态会有所不同,bottomSheets类似于具有新上下文的dialogBox,并且构建器会在父状态之外构建一个全新的小部件,以创建自己的有状态状态用状态构建器进行包装和用户自己的setState可以在此上下文中更改任何内容,而不是父项 例如:
StatefulBuilder(
builder: (context,setStateChild) {
return AnimatedPadding(...
Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,),itemExtent: 30,backgroundColor: Colors.grey[100],onSelectedItemChanged: (int val) {
setStateChild(() {
selectedReminderDay = reminderDay[val];
print("selectedReminderDay:$selectedReminderDay");
});
},);
child: ... ),
}