我想使用
setState
将按钮的颜色更改为单击时的蓝色,并将其他按钮更改为灰色以显示它们未被选中。我也希望它能改变按钮下方页面的内容。
这是目前的样子。默认情况下,表视图按钮处于选中状态,热图处于未选中状态。在这种情况下,按钮下方的“表格视图”文本会在选择“表格视图”按钮时显示。
代码如下:
class MusclesPane extends StatefulWidget {
const MusclesPane({Key? key}) : super(key: key);
@override
State<MusclesPane> createState() => _MusclesPaneState();
}
class _MusclesPaneState extends State<MusclesPane> {
EdgeInsets padding = const EdgeInsets.all(25);
Widget pageSection = const MusclesTableView();
bool tableViewIsActive = true;
bool heatmapDiagramIsActive = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: () => {
setState(() {
pageSection = const MusclesTableView();
tableViewIsActive = true;
heatmapDiagramIsActive = false;
})
},
child: ViewTypeButton(
title: "Table view", isActive: tableViewIsActive)),
InkWell(
onTap: () => {
setState(() {
pageSection = const MusclesHeatmapDiagram();
heatmapDiagramIsActive = true;
tableViewIsActive = false;
})
},
child: ViewTypeButton(
title: "Heatmap diagram",
isActive: heatmapDiagramIsActive)),
],
),
Padding(padding: padding, child: pageSection),
],
);
}
}
class ViewTypeButton extends StatelessWidget {
const ViewTypeButton({Key? key, required this.title, required this.isActive})
: super(key: key);
final String title;
final bool isActive;
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 4.0),
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
primary: isActive ? Colors.blue : Colors.grey),
child: Text(title)));
}
}
当我点击热图按钮时,没有任何反应。同样在 setState 函数中,我尝试使用
print(heatmapDiagramIsActive)
和 print(tableViewIsActive)
来检查变量是否发生变化,但没有任何输出,所以我不确定变量是否在变化。
我在想这可能是由于变量的范围。我尝试将
tableViewIsActive
和 heatmapDiagramIsActive
变量移到课堂之外;我也尝试将它们移动到 build() 函数下,但这并没有解决问题。
任何帮助将不胜感激 - 我现在已经多次回到这个问题,但我仍然坚持下去。另外,如果有任何我可以改进的 Flutter 实践,例如命名约定或任何重构建议,请告诉我,因为我是 Flutter 的新手。
正如我在评论中提到的,堆叠
InkWell
和ElevatedButton
使得ElevatedButton
正在接收输入但InkWell
不是。您可以通过将回调函数传递给ElevatedButton
并在点击按钮时调用该函数来解决这个问题:
class MusclesPane extends StatefulWidget {
const MusclesPane({Key? key}) : super(key: key);
@override
State<MusclesPane> createState() => _MusclesPaneState();
}
class _MusclesPaneState extends State<MusclesPane> {
EdgeInsets padding = const EdgeInsets.all(25);
Widget pageSection = const MusclesTableView();
bool tableViewIsActive = true;
bool heatmapDiagramIsActive = false;
selectTableView() {
setState(() {
pageSection = const MusclesTableView();
tableViewIsActive = true;
heatmapDiagramIsActive = false;
});
}
selectHeatMapView() {
setState(() {
pageSection = const MusclesHeatMapDiagram();
tableViewIsActive = false;
heatmapDiagramIsActive = true;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(height: 90),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ViewTypeButton(
title: "Table view",
isActive: tableViewIsActive,
callback: selectTableView,
),
ViewTypeButton(
title: "HeatMapDiagram",
isActive: heatmapDiagramIsActive,
callback: selectHeatMapView,
),
],
),
Padding(padding: padding, child: pageSection),
],
);
}
}
class ViewTypeButton extends StatelessWidget {
const ViewTypeButton(
{Key? key,
required this.title,
required this.isActive,
required this.callback})
: super(key: key);
final String title;
final bool isActive;
final Function callback;
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 4.0),
child: ElevatedButton(
onPressed: () => callback(),
style: ElevatedButton.styleFrom(
backgroundColor: isActive ? Colors.blue : Colors.grey),
child: Text(title)));
}
}
ElevatedButton
里面已经有InkWell
,所以再多一个是多余的。
在设计方面,当您只有几样东西可供选择时,为每个按钮使用布尔值很简单。然而,如果你想扩展到拥有更多按钮,你可以使用一个整数作为键来确定一个按钮是否被激活。您可以根据需要扩展到任意数量的按钮,而无需创建无穷无尽的布尔变量。
class MusclesPane extends StatefulWidget {
const MusclesPane({Key? key}) : super(key: key);
@override
State<MusclesPane> createState() => _MusclesPaneState();
}
class _MusclesPaneState extends State<MusclesPane> {
EdgeInsets padding = const EdgeInsets.all(25);
Widget pageSection = const MusclesTableView();
int selected = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(height: 90),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () => setState(() {
selected = 0;
pageSection = const MusclesTableView();
}),
style: ElevatedButton.styleFrom(
backgroundColor: selected == 0 ? Colors.blue : Colors.grey),
child: const Text("Table view")),
ElevatedButton(
onPressed: () => setState(() {
selected = 1;
pageSection = const MusclesHeatmapDiagram();
}),
style: ElevatedButton.styleFrom(
backgroundColor: selected == 1 ? Colors.blue : Colors.grey),
child: const Text("Heatmap diagram")),
],
),
Padding(padding: padding, child: pageSection),
],
);
}
}