【问题标题】:How to deselected other buttons when a button is selected?选择按钮时如何取消选择其他按钮?
【发布时间】:2021-09-01 22:06:42
【问题描述】:

我正在构建一个折线图,可以通过选择它们来编辑点,但是,我希望点像单选按钮一样工作,一次只能选择一个。我现在无法让它工作:

图表是通过从 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() 中将点、线和指南呈现在一个大列表中以在堆栈中呈现

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 dart flutter-provider


    【解决方案1】:

    我需要更多代码才能准确回答。

    但是,一种解决方案是提升状态。

    在 Flutter 中,将状态保持在使用它的小部件之上是有意义的。

    因此,渲染 GraphSpot 的 StatefulWidget 可以有一个 _selectedIndex 属性来保存选定的索引。然后你可以给每个 GraphSpot Widget 传递一个 onGraphSpotTap 函数。

    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 渲染

    【讨论】:

      猜你喜欢
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      • 2019-03-25
      • 1970-01-01
      相关资源
      最近更新 更多