我正在尝试使用下面的代码创建一个自定义小部件,但还没有找到一种方法来做到这一点,以便在调用 setState 函数后屏幕上显示的文本发生变化。它只是保持初始值。我还尝试在变量更改后从类外部查看变量,但也无法查看。
我尝试将容器封装在名为 CustomDatePicker 的小部件中,设置类的构造函数来初始化变量,但这并没有起作用,因为我无法在主文件中调用小部件的位置查看变量.
Color darkBlueCustom = const Color(0xFF003366);
Color lightBlueCustom = const Color(0xFFadd8e6);
List months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Container(
padding: const EdgeInsets.only(left: 10),
height: 45,
color: darkBlueCustom,
child: Align(
alignment: Alignment.centerLeft,
child: CupertinoButton(
padding: EdgeInsets.zero,
// Display a CupertinoPicker with list of months.
onPressed: () {
setState(() {
clickedMonth = true;
_showDialog(
CupertinoPicker(
magnification: 1.22,
squeeze: 1.2,
useMagnifier: true,
itemExtent: 32.0,
// This sets the initial item.
scrollController: FixedExtentScrollController(
initialItem: selectedMonth,
),
// This is called when selected item is changed.
onSelectedItemChanged: (int selectedItem) {
setState(() {
selectedMonth = selectedItem;
});
},
children:
List<Widget>.generate(months.length, (int index) {
return Center(child: Text(months[index]));
}),
),
);
});
},
// This displays the selected Month name.
child: Text(
months[selectedMonth],
style: GoogleFonts.ubuntu(
textStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: clickedMonth ? Colors.white : Colors.white38,
),
),
),
),
),
),
Text(
"$title,$selectedMonth,$clickedMonth",
),
],
),
)
我尝试过像这样制作小部件:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_fonts/google_fonts.dart';
Color darkBlueCustom = const Color(0xFF003366);
Color lightBlueCustom = const Color(0xFFadd8e6);
class CustomDatePicker extends StatefulWidget {
final String title;
final int selectedMonth;
final bool clickedMonth;
const CustomDatePicker({
super.key,
required this.title,
required this.selectedMonth,
required this.clickedMonth,
});
@override
State<CustomDatePicker> createState() => _CustomDatePickerState();
}
class _CustomDatePickerState extends State<CustomDatePicker> {
List months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
void _showDialog(Widget child) {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => Container(
height: 216,
padding: const EdgeInsets.only(top: 6.0),
// The Bottom margin is provided to align the popup above the system navigation bar.
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
// Provide a background color for the popup.
color: CupertinoColors.systemBackground.resolveFrom(context),
// Use a SafeArea widget to avoid system overlaps.
child: SafeArea(
top: false,
child: child,
),
),
);
}
@override
Widget build(BuildContext context) {
String title = widget.title;
int selectedMonth = widget.selectedMonth;
bool clickedMonth = widget.clickedMonth;
return Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Container(
padding: const EdgeInsets.only(left: 10),
height: 45,
color: darkBlueCustom,
child: Align(
alignment: Alignment.centerLeft,
child: CupertinoButton(
padding: EdgeInsets.zero,
// Display a CupertinoPicker with list of months.
onPressed: () {
setState(() {
clickedMonth = true;
_showDialog(
CupertinoPicker(
magnification: 1.22,
squeeze: 1.2,
useMagnifier: true,
itemExtent: 32.0,
// This sets the initial item.
scrollController: FixedExtentScrollController(
initialItem: selectedMonth,
),
// This is called when selected item is changed.
onSelectedItemChanged: (int selectedItem) {
setState(() {
selectedMonth = selectedItem;
});
},
children:
List<Widget>.generate(months.length, (int index) {
return Center(child: Text(months[index]));
}),
),
);
});
},
// This displays the selected month name.
child: Text(
months[selectedMonth],
style: GoogleFonts.ubuntu(
textStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: clickedMonth ? Colors.white : Colors.white38,
),
),
),
),
),
),
Text(
"$title,$selectedMonth,$clickedMonth",
),
],
),
);
}
}
参数
selectedMonth
传递给CustomDatePicker
的构造函数
只能用于设置初始选择。为了避免混淆,它应该被命名为例如preSelectedMonth
或 initiallySelectedMonth
。
您的小部件的状态应存储在
_CustomDatePickerState
中,例如
在一个名为 selectedMonth
的变量中:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_fonts/google_fonts.dart';
Color darkBlueCustom = const Color(0xFF003366);
Color lightBlueCustom = const Color(0xFFadd8e6);
class CustomDatePicker extends StatefulWidget {
final String title;
final int preSelectedMonth;
final bool clickedMonth; // Can be removed.
const CustomDatePicker({
super.key,
required this.title,
required this.preSelectedMonth,
required this.clickedMonth, // Can be removed.
});
@override
State<CustomDatePicker> createState() => _CustomDatePickerState();
}
class _CustomDatePickerState extends State<CustomDatePicker> {
final List months = [
"Select a month", // <--- Added entry to make selection easier.
"January", // Otherwise, January -> 0 and December -> 11
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
int selectedMonth = 0;
bool clickedMonth = false;
@override
void initState() {
selectedMonth = widget.preSelectedMonth; // Initialize the widget state
super.initState();
}
void _showDialog(Widget child) {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => Container(
height: 216,
padding: const EdgeInsets.only(top: 6.0),
// The Bottom margin is provided to align the popup above the system navigation bar.
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
// Provide a background color for the popup.
color: CupertinoColors.systemBackground.resolveFrom(context),
// Use a SafeArea widget to avoid system overlaps.
child: SafeArea(
top: false,
child: child,
),
),
);
}
@override
Widget build(BuildContext context) {
String title = widget.title;
return Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Container(
padding: const EdgeInsets.only(left: 10),
height: 45,
color: darkBlueCustom,
child: Align(
alignment: Alignment.centerLeft,
child: CupertinoButton(
padding: EdgeInsets.zero,
// Display a CupertinoPicker with list of months.
onPressed: () {
setState(() {
clickedMonth = true;
_showDialog(
CupertinoPicker(
magnification: 1.22,
squeeze: 1.2,
useMagnifier: true,
itemExtent: 32.0,
// This sets the initial item.
scrollController: FixedExtentScrollController(
initialItem: selectedMonth,
),
// This is called when selected item is changed.
onSelectedItemChanged: (int selectedItem) {
setState(() {
selectedMonth = selectedItem;
// Store selectedMonth
});
},
children:
List<Widget>.generate(months.length, (int index) {
return Center(child: Text(months[index]));
}),
),
);
});
},
// This displays the selected month name.
child: Text(
months[selectedMonth],
style: GoogleFonts.ubuntu(
textStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: clickedMonth ? Colors.white : Colors.white38,
),
),
),
),
),
),
Text(
"$title,$selectedMonth,$clickedMonth",
),
],
),
);
}
}
要从小部件外部访问选定的月份,您需要存储该变量。有关更多详细信息,我建议阅读应用程序状态管理。提供的信息包括状态管理方法列表。就我个人而言,我推荐
riverpod
。