【问题标题】:If Else condition problem in onPressed() property in Dart/FlutterDart/Flutter 中的 onPressed() 属性中的 If Else 条件问题
【发布时间】:2020-02-25 12:27:32
【问题描述】:

我希望在按下网格时突出显示网格中的按钮。 不幸的是,当我这样做时,整个专栏都会亮起。由于我是 Flutter/Dart 和一般编码的新手,我不确定我的问题是我缺乏逻辑还是我不了解该编码语言?

首页:

import 'package:flutter/material.dart';
import 'package:sequencer_n_lignes/utilities/sequence_class.dart';

class Home extends StatefulWidget {
  @override
  _Home createState() => _Home();
}

class _Home extends State<Home> {
  int i = 0, y = 0, indexTempo = 0;
  int countChanel = 0, countBtn = 0;
  bool isPlaying = false;
  List<Button> btnList = List();
  List<Chanel> chanelList = List();

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.grey[800],
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
              margin: EdgeInsets.fromLTRB(20, 10, 20, 10),
              decoration: BoxDecoration(
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black,
                      blurRadius: 5,
                      spreadRadius: 1,
                    )
                  ],
                  color: Colors.grey[900],
                  border: Border.all(
                    color: Colors.white,
                    width: 0.5,
                  )),
              child: Row(
                children: <Widget>[
/*__________________________________________ADD/REMOVE BUTTONS___________________*/
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      IconButton(
                        icon: Icon(Icons.remove),
                        onPressed: () {
                          for (i = 0; i < 4; i++) {
                            btnList.removeLast();
                            countBtn--;
                          }
                          setState(() {});
                        },
                      ),
                      Text('BUTTONS: $countBtn'),
                      IconButton(
                        icon: Icon(
                          Icons.add,
                        ),
                        onPressed: () {
                          for (i = 0; i < 4; i++) {
                            btnList.add(Button(
                                id: countBtn,
                                onColor: Colors.blue,
                                offColor: Colors.grey[900],
                                state: false));
                            countBtn++;
                          }
                          setState(() {});
                        },
                      ),
                    ],
                  ), //
/*_________________________________________ADD/REMOVE CHANEL___________________*/
                  Row(
                    children: <Widget>[
                      IconButton(
                        icon: Icon(Icons.remove),
                        onPressed: () {
                          chanelList.removeLast();
                          countChanel--;
                          setState(() {});
                        },
                      ),
                      Text('CHANEL: $countChanel'),
                      IconButton(
                        icon: Icon(Icons.add),
                        onPressed: () {
                          chanelList.add(
                              Chanel(id: countChanel, buttonList: btnList));
                          countChanel++;
                          setState(() {});
                        },
                      ),
                    ],
                  ),
                  SizedBox(
                    width: 30,
                  ),
/*_____________________________________________CONTROLS___________________*/
                  Row(
                    children: <Widget>[
                      IconButton(
                        icon: Icon(
                          Icons.play_arrow,
                          color: (isPlaying) ? Colors.green : Colors.white,
                        ),
                        onPressed: () {
                          if (isPlaying)
                            isPlaying = false;
                          else
                            isPlaying = true;
                          setState(() {});
                        },
                      ),
                      IconButton(
                        icon: Icon(
                          Icons.stop,
                          color: (isPlaying) ? Colors.white : Colors.red[900],
                        ),
                        onPressed: () {
                          if (isPlaying)
                            isPlaying = false;
                          else
                            isPlaying = true;
                          setState(() {});
                        },
                      ),
                      IconButton(
                        icon: Icon(
                          Icons.refresh,
                          color: Colors.white,
                        ),
                        onPressed: () {
                          for (i = 0; i < chanelList.length; i++) {
                            for (y = 0; y < btnList.length; y++) {
                              chanelList[i].buttonList[y].state = false;
                            }
                          }
                          setState(() {});
                        },
                      ),
                      RaisedButton.icon(
                        icon: Icon(
                          Icons.details,
                          color: Colors.white,
                        ),
                        label: Text('OK'),
                        color: Colors.red[900],
                        onPressed: () {
                          setState(() {});
                        },
                      )
                    ],
                  ),
                ],
              ),
            ),
/*__________________________________________ GRID ___________________*/

            Column(
              children: List.generate(countChanel, (indexChanel) {
                return Padding(
                  padding: const EdgeInsets.fromLTRB(0, 5, 0, 5),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: List.generate(countBtn, (indexBtn) {
                      return Padding(
                        padding: EdgeInsets.fromLTRB(3, 0, 3, 0),
                        child: Container(
                          decoration: BoxDecoration(
                            boxShadow: [
                              BoxShadow(
                                color: Colors.black,
                                blurRadius: 0.1,
                                spreadRadius: 0.1,
                              ),
                            ],
                            border: Border.all(
                              color: Colors.white,
                              width: 0.5,
                            ),
                          ),
                          width: 80,
                          height: 80,
//THATS WHERE THE PROBLEM IS///////////////////////////
                              child: FlatButton(
    //                            child: Text(
    //                                '${chanelList[indexChanel].id.toString()} \n${chanelList[indexChanel].buttonList[indexBtn].id.toString()}\n$indexChanel-$indexBtn\n${chanelList[indexChanel].buttonList[indexBtn].state}'),
                                color: (chanelList[indexChanel]
                                        .buttonList[indexBtn]
                                        .state)
                                    ? chanelList[indexChanel]
                                        .buttonList[indexBtn]
                                        .onColor
                                    : chanelList[indexChanel]
                                        .buttonList[indexBtn]
                                        .offColor,
                                onPressed: () {
                                  if (chanelList[indexChanel]
                                      .buttonList[indexBtn]
                                      .state) {
                                    chanelList[indexChanel]
                                        .buttonList[indexBtn]
                                        .state = false;
                                  } else {
                                    chanelList[indexChanel]
                                        .buttonList[indexBtn]
                                        .state = true;
                                  }
                                  setState(() {});
                                },
                              ),
                            ),
                          );
                        }),
                      ),
                    );
                  }),
                ),
              ],
            ),
          ),
        );
      }
    }

班级

class Button {
  int id;
  Color onColor = Colors.red[900], offColor = Colors.grey[900];
  Color actualColor;
  bool state = false;

  Button({this.id, this.onColor, this.offColor, this.state});
}

class Chanel {
  int id;
  List<Button> buttonList;
  Chanel({this.id, this.buttonList});
}

Screen shot of the app

【问题讨论】:

    标签: flutter dart conditional-statements flutter-onpressed


    【解决方案1】:

    相当大的代码,但我认为问题在于,每当您添加一个新频道时,您都会给它一个现有的按钮列表。添加新频道时尝试创建新的按钮列表

    chanelList.add(
        Chanel(
            id: countChanel,
            // Here is your problem, the reference to the buttons is the same
            // in all channels. Try creating new buttons for every channel
            buttonList: btnList,
        ),
    );
    

    【讨论】:

      【解决方案2】:

      我将首先介绍一些编程逻辑改进,然后解释为什么会得到意想不到的结果。

      1) Button 类中的实际颜色从不使用,将其删除。

      2) 除非每个按钮都有不同的 onColor 和 offColor,否则我建议将这两个移出 Button 类,或者至少将它们声明为静态。当我猜你只需要一次时,你不必要地一遍又一遍地实例化它们,这是一个非常小的内存改进(特别是因为你不会有数千个按钮)但更重要的是从 Button 类中删除它们或制作它们静态将使您的代码更易于阅读和理解,并减少传递给构造函数所需的参数数量(再次更简洁的代码)。

      3) 你的循环计数器“i”和“y”,在需要的地方声明它们。缩小变量的范围,使其仅在使用它的范围内可见。这样做有很多...很多原因,简而言之,当使用的范围比必要的范围大时,代码的可读性会降低,更难维护,并且更有可能引用非预期的变量。


      现在解决您的实际问题。问题不在于 if/else 语句,它与列表以及它们在内存中的处理方式有关。 回到我上面的第三点,总是使用尽可能小的范围。 你在这里声明你的 btnList

      class _Home extends State<Home> {
        int i = 0, y = 0, indexTempo = 0;
        int countChanel = 0, countBtn = 0;
        bool isPlaying = false;
        List<Button> btnList = List();
        List<Chanel> chanelList = List();
      

      稍后您将在此处将相同的 btnList 添加到不同的频道:

                    Text('CHANEL: $countChanel'),
                    IconButton(
                      icon: Icon(Icons.add),
                      onPressed: () {
                        chanelList.add(
                            Chanel(id: countChanel, buttonList: btnList));
                        countChanel++;
                        setState(() {});
                      },
      

      我建议回归基础,大致了解数组、列表和指针。您还应该搜索深复制和浅复制。 您在上面的代码块中所做的是为所有 chanelList 项设置相同的 btnList。

      假设您创建了包含 4 个项目的 btnList。假设您创建了具有 2 个项目的 channelList。那么 channelList[ 0 ].buttonList[ 0 ].state 将始终与 channelList[ 1 ].buttonList[ 0 ].state 相同,因为它们都指向同一个 Button。

      要得到这个:

      快速简便的解决方法是执行以下操作:

                    IconButton(
                      icon: Icon(Icons.add),
                        onPressed: () {
                        List<Button> tmpBtnList = new List<Button>();  
                        for(int i=0; i<btnList.length; i++){
                          tmpBtnList.add(new Button(id: i,state: false));
                        }
                        chanelList.add(
                            Chanel(id: countChanel, buttonList: tmpBtnList));
                        countChanel++;
                        setState(() {});
                      },
                    ),
      

      Complete code on DartPad.

      PS 我也不会像你所做的那样手动计算列表项,只需使用提供的 .length。

      【讨论】:

      • 非常感谢乌罗斯
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-11
      • 1970-01-01
      相关资源
      最近更新 更多