开关未正确更新
Switch is not updating properly
在我的 flutter 应用程序中,我有这个小部件:
class MenuPage extends StatefulWidget {
final List<Team> teams;
final List<Game> games;
const MenuPage({Key? key, required this.teams, required this.games})
: super(key: key);
@override
_MenuState createState() => _MenuState();
}
class _MenuState extends State<MenuPage> {
int _currentIndex = 0;
late TeamDataSource teamDataSource;
List<Team> teams = [];
List<Game> games = [];
List<Widget> body = [];
bool isSwitched = true;
@override
void initState() {
teams = widget.teams;
games = widget.games;
teamDataSource = TeamDataSource(teamData: teams);
body = [
RankingTable(teams: teamDataSource),
getMatches(),
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: body[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (int newIndex) {
setState(() {
_currentIndex = newIndex;
});
},
items: const [
BottomNavigationBarItem(
label: "Ranking", icon: Icon(Icons.format_list_numbered)),
BottomNavigationBarItem(
label: "Matchs", icon: Icon(Icons.sports_soccer)),
],
),
);
}
Widget getMatches() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return ListView(
children: [
Switch(
value: isSwitched,
onChanged: (newValue) {
setState(() {
isSwitched = newValue;
//print(isSwitched);
});
},
),
for (var game in games)
SizedBox(
height: constraints.maxHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: CachedNetworkImage(
imageUrl: game.homeTeamImage,
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(30, 0, 30, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
parseDate(game.date),
style: const TextStyle(
fontFamily:
"Work Sans, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol",
fontSize: 16),
),
Text(
game.time.substring(0, 5),
style: const TextStyle(
fontFamily: "Changa", fontSize: 30),
)
],
),
),
Expanded(
child: CachedNetworkImage(
imageUrl: game.awayTeamImage,
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
),
)
],
),
)
],
);
});
}
}
在 getMatches 函数中,开关小部件未正确更新。当我尝试切换按钮时,它总是回到真实值。我认为那是因为我正在使用 returns 一个小部件的函数,如果我将开关小部件放在构建方法中,它应该可以工作。有人可以告诉我我的代码有什么问题吗?
就是这个问题;将您在 getMatches 中返回的小部件提取为单独的小部件(使用其自己的 build 方法 - 首选方法)或只是包装StatefulBuilder 小部件内的 LayoutBuilder 小部件,它提供了一个闭包,用于将 setState 触发的更改封装到仅此小部件,如:
Widget getMatches() {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return LayoutBuilder() // rest of the code
}
);
}
在我的 flutter 应用程序中,我有这个小部件:
class MenuPage extends StatefulWidget {
final List<Team> teams;
final List<Game> games;
const MenuPage({Key? key, required this.teams, required this.games})
: super(key: key);
@override
_MenuState createState() => _MenuState();
}
class _MenuState extends State<MenuPage> {
int _currentIndex = 0;
late TeamDataSource teamDataSource;
List<Team> teams = [];
List<Game> games = [];
List<Widget> body = [];
bool isSwitched = true;
@override
void initState() {
teams = widget.teams;
games = widget.games;
teamDataSource = TeamDataSource(teamData: teams);
body = [
RankingTable(teams: teamDataSource),
getMatches(),
];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: body[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (int newIndex) {
setState(() {
_currentIndex = newIndex;
});
},
items: const [
BottomNavigationBarItem(
label: "Ranking", icon: Icon(Icons.format_list_numbered)),
BottomNavigationBarItem(
label: "Matchs", icon: Icon(Icons.sports_soccer)),
],
),
);
}
Widget getMatches() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return ListView(
children: [
Switch(
value: isSwitched,
onChanged: (newValue) {
setState(() {
isSwitched = newValue;
//print(isSwitched);
});
},
),
for (var game in games)
SizedBox(
height: constraints.maxHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: CachedNetworkImage(
imageUrl: game.homeTeamImage,
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(30, 0, 30, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
parseDate(game.date),
style: const TextStyle(
fontFamily:
"Work Sans, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol",
fontSize: 16),
),
Text(
game.time.substring(0, 5),
style: const TextStyle(
fontFamily: "Changa", fontSize: 30),
)
],
),
),
Expanded(
child: CachedNetworkImage(
imageUrl: game.awayTeamImage,
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
),
)
],
),
)
],
);
});
}
}
在 getMatches 函数中,开关小部件未正确更新。当我尝试切换按钮时,它总是回到真实值。我认为那是因为我正在使用 returns 一个小部件的函数,如果我将开关小部件放在构建方法中,它应该可以工作。有人可以告诉我我的代码有什么问题吗?
就是这个问题;将您在 getMatches 中返回的小部件提取为单独的小部件(使用其自己的 build 方法 - 首选方法)或只是包装StatefulBuilder 小部件内的 LayoutBuilder 小部件,它提供了一个闭包,用于将 setState 触发的更改封装到仅此小部件,如:
Widget getMatches() {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return LayoutBuilder() // rest of the code
}
);
}