选择按钮时如何取消选择其他按钮?
How to deselected other buttons when a button is selected?
我正在构建一个折线图,可以通过选择它们来编辑点,但是,我希望点像单选按钮一样工作,一次只能选择一个。我现在无法让它工作:
图表是通过从 SQflite 获取数据呈现的,然后我使用 Provider 构建它
main.dart :
FutureProvider<List<Map<String, dynamic>>?>(
create: (context) {
return RecordsDatabase.instance.getRecords();
},
initialData: null,
catchError: (_, __) => <Map<String, dynamic>>[
{'error': 'Something went wrong'}
],
child: (),
)
主页
Consumer<List<Map<String, dynamic>>?>(
builder: (context, List<Map<String, dynamic>>? records, child) {
if (records == null) {
return const CircularProgressIndicator();
} else if (records.isNotEmpty && records.first.containsKey('error')) {
return Text(records.first['error'] as String);
} else {
GraphState graph = GraphState(records: records, context: context);
return MultiProvider(
providers: [
ChangeNotifierProvider<GraphState>(create: (_) => graph),
ChangeNotifierProvider<ButtonMode>(
create: (context) => ButtonMode())
],
child: Scaffold(
backgroundColor: Colors.black,
body: Stack(children: [
Center(
child: (records.isEmpty == true)
? CircularProgressIndicator()
: graph.records.isEmpty
? Text(
'No Records',
style:
TextStyle(color: Colors.white, fontSize: 24),
)
: MyGraph()),
GraphState 模型在 MyGraph()
的 Stack 中呈现大列表中的点、线和指南
GraphState({required this.records, required this.context}) {
titles = renderSideTitleWeights();
spots = renderSpots();
spotLines = renderLines();
horizontalGuidelines = renderHorizontalLines();
graphList = new List.from(horizontalGuidelines)
..addAll(spotLines)
..addAll(spots);
}
//render the spots of the graph
//render the spots of the graph
List<GraphSpot> renderSpots() {
List<GraphSpot> spots = spotsXPos.mapIndexed<GraphSpot>((record, index) {
return GraphSpot(
x: record['xPos'],
y: record['yPos'],
date: record['record_date'],
weight: record['weight'],
id: index,
selected: false,
);
}).toList();
return spots;
}
GraphSpot 小部件在图表上呈现点:
class GraphSpot extends StatefulWidget {
final double x;
final double y;
final String date;
final double weight;
final int id;
final bool selected;
GraphSpot({
required this.x,
required this.y,
required this.date,
required this.weight,
required this.id,
required this.selected,
});
@override
_GraphSpotState createState() => _GraphSpotState();
}
class _GraphSpotState extends State<GraphSpot> {
@override
Widget build(BuildContext context) {
return Consumer<ButtonMode>( //ButtonMode change the add button to edit and delete
builder: (context, buttonMode, child) {
return Positioned(
left: widget.x - 5, //minus half of the width of the spot to center
bottom: widget.y -
10, //minus half of the height of the spot and padding to center
child: GestureDetector(
onTap: () {
!widget.selected
? buttonMode.setEditing()
: buttonMode.setAdd();
},
child: Column(
children: [
Container(
width: 40,
decoration: new BoxDecoration(
color: Colors.lightGreen,
shape: BoxShape.rectangle,
),
child: Text(widget.weight.toStringAsFixed(1),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.blue,
fontSize: 14,
fontWeight: FontWeight.bold)),
),
DecoratedBox(
decoration: selected
? BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 3, color: Colors.red))
: BoxDecoration(shape: BoxShape.circle),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
),
),
)
],
),
),
);
},
);
}
}
我不知道我的代码在哪里以及如何实现它。
我需要更多代码才能准确回答。
但是,一种解决方案是提升状态。
在 Flutter 中,将状态保持在使用它的小部件之上是有意义的。
因此呈现 GraphSpot 的 StatefulWidget 可以有一个 _selectedIndex
属性 来保存选定的索引。然后您可以将 onGraphSpotTap 函数传递给每个 GraphSpot Widget。
int? _selectedIndex;
List<GraphSpot> spots = spotsXPos.mapIndexed<GraphSpot>((record, index) {
return GraphSpot(
x: record['xPos'],
y: record['yPos'],
date: record['record_date'],
weight: record['weight'],
id: index,
selected: index == _selectedIndex ? true : false,
onGraphSpotTap: () {
setState(() {
_selectedIndex = index;
});
}
);
}).toList();
然后在您的 GraphSpot 中添加新的 onGraphSpotTap 属性。
class GraphSpot extends StatelessWidget {
.....
final VoidCallback? onGraphSpotTap;
....
onTap: onGraphSpotTap
不要忘记根据其选择修改 GraphSpot Widget 渲染 属性
我正在构建一个折线图,可以通过选择它们来编辑点,但是,我希望点像单选按钮一样工作,一次只能选择一个。我现在无法让它工作:
图表是通过从 SQflite 获取数据呈现的,然后我使用 Provider 构建它
main.dart :
FutureProvider<List<Map<String, dynamic>>?>(
create: (context) {
return RecordsDatabase.instance.getRecords();
},
initialData: null,
catchError: (_, __) => <Map<String, dynamic>>[
{'error': 'Something went wrong'}
],
child: (),
)
主页
Consumer<List<Map<String, dynamic>>?>(
builder: (context, List<Map<String, dynamic>>? records, child) {
if (records == null) {
return const CircularProgressIndicator();
} else if (records.isNotEmpty && records.first.containsKey('error')) {
return Text(records.first['error'] as String);
} else {
GraphState graph = GraphState(records: records, context: context);
return MultiProvider(
providers: [
ChangeNotifierProvider<GraphState>(create: (_) => graph),
ChangeNotifierProvider<ButtonMode>(
create: (context) => ButtonMode())
],
child: Scaffold(
backgroundColor: Colors.black,
body: Stack(children: [
Center(
child: (records.isEmpty == true)
? CircularProgressIndicator()
: graph.records.isEmpty
? Text(
'No Records',
style:
TextStyle(color: Colors.white, fontSize: 24),
)
: MyGraph()),
GraphState 模型在 MyGraph()
的 Stack 中呈现大列表中的点、线和指南GraphState({required this.records, required this.context}) {
titles = renderSideTitleWeights();
spots = renderSpots();
spotLines = renderLines();
horizontalGuidelines = renderHorizontalLines();
graphList = new List.from(horizontalGuidelines)
..addAll(spotLines)
..addAll(spots);
}
//render the spots of the graph
//render the spots of the graph
List<GraphSpot> renderSpots() {
List<GraphSpot> spots = spotsXPos.mapIndexed<GraphSpot>((record, index) {
return GraphSpot(
x: record['xPos'],
y: record['yPos'],
date: record['record_date'],
weight: record['weight'],
id: index,
selected: false,
);
}).toList();
return spots;
}
GraphSpot 小部件在图表上呈现点:
class GraphSpot extends StatefulWidget {
final double x;
final double y;
final String date;
final double weight;
final int id;
final bool selected;
GraphSpot({
required this.x,
required this.y,
required this.date,
required this.weight,
required this.id,
required this.selected,
});
@override
_GraphSpotState createState() => _GraphSpotState();
}
class _GraphSpotState extends State<GraphSpot> {
@override
Widget build(BuildContext context) {
return Consumer<ButtonMode>( //ButtonMode change the add button to edit and delete
builder: (context, buttonMode, child) {
return Positioned(
left: widget.x - 5, //minus half of the width of the spot to center
bottom: widget.y -
10, //minus half of the height of the spot and padding to center
child: GestureDetector(
onTap: () {
!widget.selected
? buttonMode.setEditing()
: buttonMode.setAdd();
},
child: Column(
children: [
Container(
width: 40,
decoration: new BoxDecoration(
color: Colors.lightGreen,
shape: BoxShape.rectangle,
),
child: Text(widget.weight.toStringAsFixed(1),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.blue,
fontSize: 14,
fontWeight: FontWeight.bold)),
),
DecoratedBox(
decoration: selected
? BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 3, color: Colors.red))
: BoxDecoration(shape: BoxShape.circle),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
),
),
)
],
),
),
);
},
);
}
}
我不知道我的代码在哪里以及如何实现它。
我需要更多代码才能准确回答。
但是,一种解决方案是提升状态。
在 Flutter 中,将状态保持在使用它的小部件之上是有意义的。
因此呈现 GraphSpot 的 StatefulWidget 可以有一个 _selectedIndex
属性 来保存选定的索引。然后您可以将 onGraphSpotTap 函数传递给每个 GraphSpot Widget。
int? _selectedIndex;
List<GraphSpot> spots = spotsXPos.mapIndexed<GraphSpot>((record, index) {
return GraphSpot(
x: record['xPos'],
y: record['yPos'],
date: record['record_date'],
weight: record['weight'],
id: index,
selected: index == _selectedIndex ? true : false,
onGraphSpotTap: () {
setState(() {
_selectedIndex = index;
});
}
);
}).toList();
然后在您的 GraphSpot 中添加新的 onGraphSpotTap 属性。
class GraphSpot extends StatelessWidget {
.....
final VoidCallback? onGraphSpotTap;
....
onTap: onGraphSpotTap
不要忘记根据其选择修改 GraphSpot Widget 渲染 属性