首先,我创建了一个设计好的 Bottom Sheet 格,其中有两个列表在 CupertinoPicker
的帮助下显示数字(左侧)和选项(小时、天、周、月) > 小部件,
数字取决于我选择的选项,如果我选择小时,左侧的数字应该是1-24,如果我选择星期,数字应该是1-4,如果我选择日期,数字应该是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','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'];
List<String> reminderMonthsVal =['1','2','3','4','5','6','7','8','9','10','11','12'];
List<String> reminderWeeksVal =['1','2','3','4'];
String selectedReminderVal='1';
String selectedReminderDay ='hour';
Bottom Sheet 代码:
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','day','week','month']; reminderHoursVal
.map(
(item) => Center(
child: Text(
item,
style: TextStyle(
fontSize: 16,
// fontWeight:FontWeight.bold,
),
),
),
)
.toList()),
),
Expanded(
child: CupertinoPicker(
scrollController: new FixedExtentScrollController(
initialItem: 0,
),
itemExtent: 30,
backgroundColor: Colors.grey[100],
onSelectedItemChanged: (int val) {
setState(() {
selectedReminderDay = reminderDay[val];
print("selectedReminderDay:$selectedReminderDay");
});
},
children: reminderDay
.map(
(item) => Center(
child: Text(
item,
style: TextStyle(
fontSize: 16,
// fontWeight:FontWeight.bold,
),
),
),
)
.toList()),
),
])
),
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, right: 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
)),
),
)
],
),
)
],
),
)
),
);
},
);
}
屏幕截图:
最佳答案
当我们在现有状态下创建新的上下文小部件时,状态会变得不同,bottomSheets 类似于具有新上下文的对话框,构建器从父状态构建一个全新的小部件,以创建自己的有状态状态用有状态构建器包装它并使用自己的 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: ... ),
}
关于flutter - 为什么选定的值没有反射(reflect)在带有 flutter 的 showModalBottomSheet 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63474493/