Цветные контейнеры в массиве флаттера - PullRequest
0 голосов
/ 04 апреля 2019

Вопрос обновлен 10 апреля:

Привет! Я все еще застрял и не могу заставить это работать: (

Я пытаюсь создать приложение, в котором пользователь ответит в общей сложности на 3 вопроса, прежде чем перейти к экрану результатов. Чтобы показать ход вопросов, будет 3 цветных контейнера подряд. Вначале строка будет, например, синей, но когда пользователь ответит правильно - контейнер для этого вопроса станет зеленым, а если ответ неправильный, контейнер станет красным.

Я мог бы действительно использовать некоторую дополнительную помощь здесь.

Ниже я сделал код настолько простым, насколько я могу, с разными цветами, просто чтобы показать разные элементы в списке.

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

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 = "";

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

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

  Widget myListBuilder() {
    return ListView.builder(
      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)),
              ),
               Container(
                width: 50.0,
                child: TextField(
                  textAlign: TextAlign.center,
                  autofocus: true,
                  keyboardType: TextInputType.number,
                  onChanged: (val) {
                    userAnswer = val;
                  },
                ),
              ),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  submitPressed(0);
                },
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  buildContainer(context, 0),
                  buildContainer(context, 1),
                  buildContainer(context, 2)
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

1 Ответ

1 голос
/ 05 апреля 2019

Хорошо, я собираюсь предположить несколько вещей в этом ответе, поэтому измените их при необходимости.Используемые цвета: Colors.blue для цвета по умолчанию, Colors.green для правильного и Colors.red для неправильного.

Сначала вы должны инициализировать список цветов, каждый из которых будет синимтак как это цвет по умолчанию:

List<Color> colors = [Colors.blue, Colors.blue, Colors.blue ..... Colors.blue] 
//You will write Colors.blue ten times as there are 10 boxes.

Я собираюсь предположить, что вы используете ListView.builder здесь, так как вы не указали его в своем примере кода.Вы должны построить свой ListView следующим образом:

//Place this within your widget tree
ListView.builder(
  itemBuilder: buildContainer,
  itemCount: 10,
);

Затем вам нужно будет изменить свой метод buildContainer, так как для параметра itemBuilder требуется метод, который должен принимать context и index и выводитьвиджет, следовательно:

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))
        ),
      ),
    )
  );
}

Затем будут созданы 10 блоков, каждый из которых получил свой цвет со своей позиции в списке цветов, созданных ранее.Теперь вам просто нужно изменить цвет, когда они закончены.Используя ваш пример кода:

if (userAnswer == widget.sum.toString()) {
  setState(() {
    correction = widget.sum.toString();
    //Here we will instead set the specific color in the array
    colors[index] = Colors.green;
  });
} else {
  correction = widget.sum.toString();
  colors[index] = Colors.red;
}

Единственное, что вам нужно сделать, это убедиться, что функция, когда вы нажимаете Далее, принимает переменную, которая является индексом вопросов, то есть номером вопроса, на котором вы находитесь.

...