所有卡的TextField值更改

时间:2019-07-17 14:55:30

标签: flutter dart

我正在制作体育馆日记,每步动作都有“卡片”,其中包括“ setsreps kg”。因此,代码在视图中生成了尽可能多的卡“ Squat”和“ Front-squat”。这里的问题是我在两张卡中都使用controllerSets。如果我将“下蹲”设置编号更改为“ 2”,则“前蹲”设置编号也更改为“ 2”,因为它使用相同的controllerSets TextEditingController。这是我的问题,请考虑甚至可以有10个移动,我不希望为每个移动创建10 x 3控制器。我的问题是我应该如何构建此功能?完整的代码可以在这里找到:

return Column(
  children: <Widget>[
    Text(
      _programMovesGen(program)[index],
      textAlign: TextAlign.center,
      style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
    ), // Move name
    Row(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        new Flexible(
          child: Padding(
            padding: const EdgeInsets.all(18.0),
            child: new TextFormField(
                controller: controllerSets,
                keyboardType: TextInputType.number,
                inputFormatters: [
                  LengthLimitingTextInputFormatter(2),
                ]),
          ),
        ),
        Text(
          "sets ",
          textAlign: TextAlign.center,
          style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
        ),
        new Flexible(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: new TextFormField(
                controller: controllerReps,
                keyboardType: TextInputType.number,
                inputFormatters: [
                  LengthLimitingTextInputFormatter(2),
                ]),
          ),
        ),
        Text(
          "reps",
          textAlign: TextAlign.center,
          style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
        ),
        new Flexible(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: new TextFormField(
                controller: controllerKgs,
                keyboardType: TextInputType.number,
                inputFormatters: [
                  LengthLimitingTextInputFormatter(2),
                ]),
          ),
        ),
        Text(
          "kg",
          textAlign: TextAlign.center,
          style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
        ),
        Container(
            height: 60,
            width: 60,
            margin: const EdgeInsets.all(16.0),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              border: Border.all(
                color: Colors.pink,
                width: 3.5,
              ),
            ),
            child: IconButton(
                icon: Icon(
                  IconData(57669, fontFamily: 'MaterialIcons'),
                  size: 38,
                  color: Colors.red,
                ),
                onPressed: () => {
                      _saveMove(_programMovesGen(program)[index]),
                    })),

        ///TODO add to db and previous added move
      ],
    ),
  ],
);

}

https://pastebin.com/m6zVLUAD

enter image description here

3 个答案:

答案 0 :(得分:0)

像这样制作TextEditingControllers的数组:

List<TextEditingController> controllerSets = new List<TextEditingController>();
List<TextEditingController> controllerReps = new List<TextEditingController>();
List<TextEditingController> controllerKgs = new List<TextEditingController>();

TextEditingController sets = new TextEditingController(text: '3');
TextEditingController reps = new TextEditingController(text: '6');
TextEditingController kgs = new TextEditingController(text: '60');

在您的initState方法中,执行以下操作:

@override
void initState() {
  super.initState();
}

现在在_saveMove函数中传递该列表索引,因此它将如下所示:

_saveMove(String moveName, int index) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      debugPrint("BEFORE SAVEDMOVES " + savedMoves);

      savedMoves += (moveName != "")
          ? moveName +
              ": " +
              controllerSets[index].text +
              " sets " +
              controllerReps[index].text +
              " reps " +
              controllerKgs[index].text +
              " kg\n"
          : "";
      prefs.setString('history', savedMoves);
    });
  }

您的_buildCardContent()函数将被更改,因为您还必须在控制器列表中传递索引:

Widget _buildCardContent(int index) {
    controllerSets.add(sets);
    controllerReps.add(reps);
    controllerKgs.add(kgs);

    return Column(
      children: <Widget>[
        Text(
          _programMovesGen(program)[index],
          textAlign: TextAlign.center,
          style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
        ), // Move name
        Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new Flexible(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: new TextFormField(
                    controller: controllerSets[index],
                    keyboardType: TextInputType.number,
                    inputFormatters: [
                      LengthLimitingTextInputFormatter(2),
                    ]),
              ),
            ),
            Text(
              "sets ",
              textAlign: TextAlign.center,
              style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
            ),
            new Flexible(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: new TextFormField(
                    controller: controllerReps[index],
                    keyboardType: TextInputType.number,
                    inputFormatters: [
                      LengthLimitingTextInputFormatter(2),
                    ]),
              ),
            ),
            Text(
              "reps",
              textAlign: TextAlign.center,
              style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
            ),
            new Flexible(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: new TextFormField(
                    controller: controllerKgs[index],
                    keyboardType: TextInputType.number,
                    inputFormatters: [
                      LengthLimitingTextInputFormatter(2),
                    ]),
              ),
            ),
            Text(
              "kg",
              textAlign: TextAlign.center,
              style: TextStyle().copyWith(color: Colors.black, fontSize: 18.0),
            ),
            Container(
                height: 60,
                width: 60,
                margin: const EdgeInsets.all(16.0),
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(
                    color: Colors.pink,
                    width: 3.5,
                  ),
                  /*gradient: RadialGradient(
                  radius: 0.50,
                  colors: [
                    Colors.blue,
                    Colors.yellowAccent,
                  ],
                ),*/
                ),
                child: IconButton(
                    icon: Icon(
                      IconData(57669, fontFamily: 'MaterialIcons'),
                      size: 38,
                      color: Colors.red,
                    ),
                    onPressed: () => {
                          _saveMove(_programMovesGen(program)[index], index),
                        })),

            ///TODO add to db and previous added move
          ],
        ),
      ],
    );
  }

答案 1 :(得分:0)

尝试将gym card分隔成自己的class并在需要时随时调用 像这样

class GymCard extends StatefulWidget {
  final String excerciseName;

  GymCard({Key key, this.excerciseName}) : super(key: key);
  @override
  _GymCardState createState() => _GymCardState();
}

class _GymCardState extends State<GymCard> {
  TextEditingController _setsController, _repsController, _weightController;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _setsController = TextEditingController();
    _repsController = TextEditingController();
    _weightController = TextEditingController();
  }
  void _getExcerciseDetails (){
     _setsController.text;
    _repsController.text;
    _weightController.text;
    //do something with them
  }
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        //Text for the name of exercise
        //Text(widget.excerciseName)
        Row(
          children: <Widget>[
            TextField(
              controller: _setsController,
            ),
            //text for sets word
            TextField(
              controller: _repsController,
            ),
            //text for reps word
            TextField(
              controller: _weightController,
            ),
            //text for weight word
            //icon button
          ],
        )
      ],
    );
  }

 }

如果您有类似程序class的内容,则可以将其作为parameter添加到widget中,然后 将其传递给controllers函数中的initstate

//in initstate
_setsController.text = widget.program.sets;
//do this for the other two controllers 

现在返回程序屏幕

return Scaffold(
  body: ListView(
       children: <Widget>[
              GymCard(program:programs[0],excerciseName : 'Squat'),
              GymCard(program:programs[1],excerciseName : 'bench press') //and so on
             ]
    )
 )

答案 2 :(得分:-1)

对不起,但是您需要为每个TextField使用不同的TextEditingController。正如此行在documentation中所建议的。

将TextEditingController连接到文本字段 将TextEditingController提供给TextField或TextFormField。 将这两个课程组合在一起后,就可以开始听文本字段的更改了。 因此,您需要为屏幕上的每个文本字段使用单独的TextEditingController并从中获取数据。

解决此问题的方法:

  1. 从initState方法创建一个数组列表,并将该textEditingController传递给您的textField小部件。
  2. 使用blocPattern并流式传输更多内容-> link