반응형

0. 들어가기

-. 앞 포스트 대비 퀴즈 목록의 형태를 바꿨다. 작업하다보니 이래야 할거같더라..

-. map 함수를 이용해서 다수의 widget을 추가해본다.

1. json object 구조 변경

-. DnD 성향 테스트를 예시로, 퀴즈 답변을 기존의 json 구조에서 list로 변경했다. 출처링크

-. 코드로 바로 보자. "answers" key 내부를 {"답변번호": "답변내용"} 의 dict 형식에서 -> [{"answerNum": "답변번호", "answerText": "답변내용"}]의 List 형식으로 변경함.

기존 형식

Map<String, Map<String, Object>> dndAlignment = {
    "1": {
      "question":
          "Family elders are expressing disapproval of you to the rest of the family. Do you:",
      "answers": {
        "1": "Accept the criticism and change your ways?",
        "2": "Seek a compromise with them?",
        "3":
            "Besmirch the reputation of those expressing disapproval as you ignore their scorn?",
        "4": "Silence them any way you can?"
      }
    },
    ...
}

----
새 형식

Map<String, Map<String, Object>> dndAlignment = {
    "1": {
      "question":
          "Family elders are expressing disapproval of you to the rest of the family. Do you:",
      "answers": [
        {
          "answerNum": "1",
          "answerText": "Accept the criticism and change your ways?"
        },
        {"answerNum": "2", "answerText": "Seek a compromise with them?"},
        {
          "answerNum": "3",
          "answerText":
              "Besmirch the reputation of those expressing disapproval as you ignore their scorn?"
        },
        {"answerNum": "4", "answerText": "Silence them any way you can?"}
      ]
    },
    ...
}

2. map으로 답변 버튼 출력

-. List로 변경한 이유가 여기에 있는데, 답변 목록을 List<Map<String, String>> 형식으로 뽑아낼 수 있으니, 기존의 key를 뽑아내고 하는 지저분한 코드 없이 바로 map에 대입이 가능하다. 

기존 코드
body: Column(
              Question(dndAlignment["$questionIndex"]?['question'] as String),
              ...(dndAlignment["$questionIndex"]?['answers']
                      as Map<String, String>)
                  .keys
                  .map((answerNum) {
                return Answer(
                    (dndAlignment["$questionIndex"]?['answers']
                        as Map<String, String>)[answerNum] as String,
                    buttonClicked);
              }).toList(),
            ],
          )

----
새 코드
body: Column(
            children: [
              Question(dndAlignment["$questionIndex"]?['question'] as String),
              ...(dndAlignment["$questionIndex"]?['answers']
                      as List<Map<String, String>>)
                  .map((answer) {
                return Answer(answer, buttonClicked);
              }).toList(),
            ],
          )

3. Answer 위젯 수정 

-. 기존의 Answer widget은 text를 받아서 출력했는데, 이제는 Map<String, String> 형태를 받아야 한다.

import 'package:flutter/material.dart';

class Answer extends StatelessWidget {
  final Map<String, String> answer;
  final VoidCallback quizHandler;

  Answer(this.answer, this.quizHandler);

  @override
  Widget build(BuildContext context) {
    final String answerText = answer["answerText"] as String;
    // TODO: implement build
    // return Text(question);
    return Container(
      width: double.infinity,
      alignment: Alignment.centerLeft,
      margin: const EdgeInsets.all(10),
      // color: Colors.blue[200],
      child: ElevatedButton(
        onPressed: quizHandler,
        style: ButtonStyle(
          minimumSize: MaterialStateProperty.all(const Size(double.infinity, 40)),
          backgroundColor: MaterialStateProperty.all(Colors.red),
          // foregroundColor: MaterialStateProperty.all(Colors.transparent),
        ),
        child: Text(
          answerText,
          style: const TextStyle(fontSize: 20),
          textAlign: TextAlign.left,
        ),
      ),
    );
  }
}
728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기