изменить цвет контейнера из списка

#list #colors #flutter #state

#Список #Цвет #трепетание #состояние

Вопрос:

Ранее я задавал вопрос относительно списков в Flutter. Я получил хорошую помощь, но в том же списке возникли новые проблемы. Поскольку этот новый probelm имеет другой характер, то первоначальный вопрос, который я задал, — это новый вопрос.

У меня есть список (приведенный ниже код упрощен из моего рабочего кода, чтобы прояснить мою проблему) контейнеров синего цвета.

Когда пользователь вводит 5 и нажимает кнопку «отправить», цвет первого контейнера должен измениться на зеленый (если не 5, кнопка должна стать красной). При втором нажатии пользователем кнопки «отправить» второй контейнер должен изменить цвет. И так далее…

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу заставить свой прирост списка работать.

       import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'listing 4',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: FirstScreen(),
    );
  }
}

class FirstScreen extends StatefulWidget {
  @override
  _FirstScreenState createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  int sum = 5;
  String userAnswer;
  String correction = "";
  var _controller = new TextEditingController();
  int _counter = 1;

  List<Color> colors = [Colors.blue, Colors.blue, Colors.blue];

  submitPressed(int index) {
    if (userAnswer == sum.toString()) {
      setState(() {
        correction = sum.toString();
        colors[index] = Colors.green;
      });
    } else {
      setState(() {
        correction = sum.toString();
        colors[index] = Colors.red;
      });
    }
  }

  Widget myTextField() {
    return Container(
      width: 50.0,
      child: TextField(
        controller: _controller,
        textAlign: TextAlign.center,
        autofocus: true,
        keyboardType: TextInputType.number,
        onChanged: (val) {
          userAnswer = val;
        },
      ),
    );
  }

  Widget myListBuilder() {
    return Container(
      height: 50.0,
      width: 300.0,
      child: Padding(
        padding: const EdgeInsets.all(10.0),
        child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 3,
          itemBuilder: buildContainer,
        ),
      ),
    );
  }

  Widget buildContainer(BuildContext context, int index) {
    return Container(
        child: Padding(
      padding: const EdgeInsets.only(top: 10.0),
      child: Container(
        height: 20.0,
        width: 15.0,
        decoration: BoxDecoration(
            color: colors[index], //this is the important line
            borderRadius: BorderRadius.all(Radius.circular(8.0))),
      ),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('Listing 4'),
      ),
      body: Container(
        child: Center(
           child: Column(
            children: <Widget>[
              Padding(
               padding: EdgeInsets.only(top: 10.0),
               child: Text('Correct answer is 5',
                    style: TextStyle(fontSize: 20.0)),
              ),
              myTextField(),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  setState(() {
                    submitPressed(0);  //This will naturally only give index 0
                  });
                },
              ),
              myListBuilder(),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  buildContainer(context, 0),
                  buildContainer(context, 1),
                  buildContainer(context, 2)
                ],
              ),
              RaisedButton(
                child: Text('Next'),
                onPressed: () {
                  _counter  ;
                  _controller.clear();
                  myTextField();
                },
              ),
              Text('This should be container no: $_counter'),
            ],
          ),
        ),
      ),
    );
  }
}
  

Комментарии:

1. Я не вижу, где вы используете myListBuilder , вы забыли опубликовать код? Также, когда вы меняете на red вы забыли setState .

2. Работаю над исправлением этого (спасибо, что указали на это). По-прежнему инкремент не будет работать :-/

3. Код обновлен, и вы можете видеть как myListBuilder, так и buildContainer. Причина этого заключается только в ясности в этом вопросе.

Ответ №1:

Я не могу понять, почему у вас это есть

 submitPressed(0);
  

Этот код работает:

 import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'listing 4',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: FirstScreen(),
    );
  }
}

class FirstScreen extends StatefulWidget {
  @override
  _FirstScreenState createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  int sum = 5;
  String userAnswer;
  String correction = "";
  var _controller = new TextEditingController();
  int _counter = 0;

  List<Color> colors = [Colors.blue, Colors.blue, Colors.blue];

  submitPressed(int index) {
    if (userAnswer == sum.toString()) {
      setState(() {
        correction = sum.toString();
        colors[index] = Colors.green;
      });
    } else {
      setState(() {
        correction = sum.toString();
        colors[index] = Colors.red;
      });
    }
  }

  Widget myTextField() {
    return Container(
      width: 50.0,
      child: TextField(
        controller: _controller,
        textAlign: TextAlign.center,
        autofocus: true,
        keyboardType: TextInputType.number,
        onChanged: (val) {
          userAnswer = val;
        },
      ),
    );
  }

  Widget myListBuilder() {
    return Container(
      height: 50.0,
      width: 300.0,
      child: Padding(
        padding: const EdgeInsets.all(10.0),
        child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 3,
          itemBuilder: buildContainer,
        ),
      ),
    );
  }

  Widget buildContainer(BuildContext context, int index) {
    return Container(
        child: Padding(
          padding: const EdgeInsets.only(top: 10.0),
          child: Container(
            height: 20.0,
            width: 15.0,
            decoration: BoxDecoration(
                color: colors[index], //this is the important line
                borderRadius: BorderRadius.all(Radius.circular(8.0))),
          ),
        ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('Listing 4'),
      ),
      body: Container(
        child: Center(
          child: Column(
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(top: 10.0),
                child: Text('Correct answer is 5',
                    style: TextStyle(fontSize: 20.0)),
              ),
              myTextField(),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  setState(() {
                    submitPressed(_counter);
                  });
                },
              ),
              myListBuilder(),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  buildContainer(context, 0),
                  buildContainer(context, 1),
                  buildContainer(context, 2)
                ],
              ),
              RaisedButton(
                child: Text('Next'),
                onPressed: () {
                  setState(() {
                    _counter  ;
                  });
                  _controller.clear();
                  myTextField();
                },
              ),
              Text('This should be container no: ${_counter  1}'),
            ],
          ),
        ),
      ),
    );
  }
}
  

Я изменил _counter, чтобы он действовал как индекс и использовал его в качестве параметра метода submitPressed .
Я также ввел приращение в setState, или вы увидели новое число только после нажатия кнопки отправки.

Комментарии:

1. Я не могу отблагодарить вас достаточно: D Иногда, когда я провожу пробное тестирование и ошибки, я добавляю материал, который забываю удалить в «бета» коде. Приращение было небрежным и просто для доказательства того, что я пытался сделать. Но я буду использовать его для перехода к следующему экрану после определенного количества вопросов. Еще раз спасибо! Это означает, что я могу продолжить свою работу 🙂

2. Нет проблем! ^_^ Когда я добавляю отладочные материалы в код (я тоже это делаю!), Я лично предпочитаю добавлять // TODO , поэтому я могу легко отследить их с помощью своих инструментов IDE, когда захочу их удалить.

3. Хорошая идея. Я это осуществлю 🙂