아직 2편 화면분할을 못 봤다면? 보러가기 👀
반갑습니다 여러분! 코딩백조입니다🦢
지난 시간에는 우리의 앱 화면을 main.dart 에 만드는 것이 아니라, quiz_screen.dart 에다가 나눠서 만들어 봤었어요! 그 위젯을 메인 함수 내에서 불러오기도 했구요.
오늘은 작성한 질문/대답을 통해 어떻게 퀴즈가 진행될 지에 대해 설명해드릴게요!
📍 [ 3 / 7 ] 질문/대답의 구조 소개, List & Map 소개
대답 버튼을 눌렀을 때 어떻게 화면이 바뀔지에 대해 고민해보는 시간이 될거에요.
또한, setState 라고 하는 함수에 대해 알아볼게요!
플러터에서 데이터를 어떻게 저장하고 관리할 지에 대해 짧게 설명해드리겠습니다 🤩
그럼, 바로 출발 ~~ 💨
지난 시간에 숙제로 드렸던 질문과 대답에 대해 하나 알려드릴 게 있어요!
뭔가.. 평소에 우리가 보는 형식이랑은 달라요. 그냥 문자가 아니라 막 [ ] { } : 이런게 있어요. 그쵸?! 🤨
[
{
'questionText': '평화로운 휴일!\n간만에 찾은 자유시간,\n당신은 무엇을 하시겠습니까?',
'answers': [
{'text': '나에게 휴식이란 없다. 소맥 달려~!', 'score': 8},
{'text': '운동은 못참지! 헬스장 가기', 'score': 6},
{'text': '노래 들으며 산책이나 할까?', 'score': 4},
{'text': '피곤해.. 누워서 넷플 정주행하기', 'score': 2},
],
},
];
이건 Dart 에서 사용하는 컴퓨터 언어 문법이에요!
으으.. 영문법도 질리는데 코딩에도 문법이.. 라고 생각 할 수도 있지만!!
사람마다 말투가 다르고 주로 쓰는 단어가 있듯, 컴퓨터가 쓰는 말투라고 생각해 주세요. 🤪
짧게 이 문법들을 설명해 드릴게요! 따라 하지는 않으셔도 됩니다 😉
리스트, 말 그대로 목록 입니다.
대괄호 안에 넣어진 항목을 순서대로 (0번째 1번째 2번째 ...) 접근할 수 있게끔 해주는 문법이에요!
새로운 리스트를 만들려면 이렇게 하면 됩니다.
List breakfast = ["bread", "egg", "strawberry"];
오늘 제 아침을 리스트로 정리해 봤습니다. 🤤
첫 번째 항목인 "bread" 를 꺼내고 싶으면, String first = breakfast[0];
이렇게 변수 이름 뒤 [ ] 안에다가 순서를 숫자로 넣어주면 됩니다!
0은 컴퓨터에게 첫 번째라는 뜻이라서, first 변수에 "bread" 가 저장될거에요!
우리 숙제를 보면 맨 앞뒤에 [ ] 로 묶여있죠? 여러 개의 질문을 목록으로 모았다! 라는 뜻입니다 😲
맵, 혹은 딕셔너리 라고 부르는 이 문법은, 좀 독특해요.
사전이랑 똑같은 형식을 취하는데요,
사전에는 한 단어 당 여러 뜻이 올 수 있지만! 똑같은 단어가 두 번 기록되지는 않죠?
그리고 단어의 뜻을 찾기 위해 사전을 쓰는 것 처럼,
단어(key)를 통해 단어의 뜻(value)을 찾아주는 구조가 바로 맵 입니다!
맵은 0번째 1번째.. 같은 순서가 없구요, 항상 key 를 통해 값에 접근합니다.
Map coffee = {
'ice': 'Americano',
'hot': 'Latte',
},
이게 바로 Map 입니다!
제가 커피를 차갑게 먹는지, 뜨겁게 먹는지 정리했어요. ☕️
ice 와 hot 라는 key 값에다가 각각 아메리카노와 라떼를 value 로 넣었습니다.
차가운 커피로 뭘 먹는지 확인하고 싶으면, String coldCoffee = coffee["ice"];
이렇게 [" "] 따옴표 내부에 key 값을 넣어주면 됩니다! coldCoffee 라는 변수에 "Americano" 라는 값이 저장 되었겠죠?
이렇게 list 와 map 에 대해 간단하게 알아보았습니다.
왜냐면 우리의 질문 대답이 그렇게 이뤄졌기 때문이죠!!
[
{
'questionText': '평화로운 휴일!\n간만에 찾은 자유시간,\n당신은 무엇을 하시겠습니까?',
'answers': [
{'text': '나에게 휴식이란 없다. 소맥 달려~!', 'score': 8},
{'text': '운동은 못참지! 헬스장 가기', 'score': 6},
{'text': '노래 들으며 산책이나 할까?', 'score': 4},
{'text': '피곤해.. 누워서 넷플 정주행하기', 'score': 2},
],
},
{
'questionText': '카페에서 이상형을 본 당신!\n무엇을 하시겠습니까?',
'answers': [
{'text': '말은 부끄러워서 못 걸거 같다. 눈에만 담기', 'score': 2},
{'text': '가서 말을 걸어본다. 혹시 애인 있으세요?', 'score': 8},
{'text': '나 오늘 .. 상태 괜찮나? 일단 거울 보기', 'score': 4},
{'text': '그 사람 앞에 쪽지를 남기고 떠난다.', 'score': 6},
],
},
{
'questionText': '안 친한 친구에게 받은 카톡.\n너 이런 점은 고쳤으면 좋겠어.',
'answers': [
{'text': '알겠어 근데 내 일은 내가 알아서 할게..^^', 'score': 4},
{'text': '이렇게 생각할 수도 있군. 고쳐본다고 한다.', 'score': 2},
{'text': '어쩌라는거지? 참견 말라고 한 소리 한다.', 'score': 8},
{'text': '굳이 얼굴 붉히기 싫다. 읽씹한다.', 'score': 6},
],
},
];
어떤가요? 맵과 리스트가 몇 개나 보이시나요?
이 전체가 하나의 리스트죠! 3개의 map 을 가지고 있네요.
각각의 map 은 questionText 와 answers 라는 key 값을 가지고 있고, answers 의 value 값은 리스트네요!
그 리스트는 또 4개의 map 으로 이루어져있습니다. 각각 text 와 score 라는 key 를 가지고 있네요.
휴.. 복잡하죠? 😮💨
그래도 이제 좀 파악이 되었으니 설명을 할 수 있겠어요!!
자.. 이 두개를 보면 어디가 어디로 연결 되어있는지 파악이 되실거에요!
{
'questionText': '평화로운 휴일!\n간만에 찾은 자유시간,\n당신은 무엇을 하시겠습니까?',
'answers': [
{'text': '나에게 휴식이란 없다. 소맥 달려~!', 'score': 8},
{'text': '운동은 못참지! 헬스장 가기', 'score': 6},
{'text': '노래 들으며 산책이나 할까?', 'score': 4},
{'text': '피곤해.. 누워서 넷플 정주행하기', 'score': 2},
],
},
questionText 가 바로 질문,
answers 의 text 가 바로 대답이었습니다!! 🤩
그리고 score 을 통해 각각 대답을 눌렀을 때 더해질 점수가 정해지겠죠?
이렇게 미리 질문과 대답을 정한 이유가 뭐냐구요?
매번 Text 와 ElevatedButton 에 값을 넣어주지 않고, 이 질문과 대답 리스트에서 값을 가져가는 것이 코드를 효율적으로 짤 수 있기 때문이죠!
필요한 데이터를 한 곳에 몰아넣고 나중에 가져가는 게 훨씬 관리하기 쉽답니다.😉
자, 이제 본격적으로 이것들을 활용해보겠습니다!! 😎
간단하게 첫 화면이 동작하는지만 보고 넘어가겠습니다.
우리가 써온 질문과 대답을 새로운 파일에다가 넣어줄게요!
question_list.dart 라는 파일을 새로 만들겠습니다.
그 다음, 이 리스트를 변수에 저장할게요!
List<Map<String, dynamic>> questionList = ...
라고 써주시고, ... 부분에 써온 코드를 입력해줍시다.
List<Map<String, dynamic>>
은 무슨 뜻이냐구요? 🤔
Dart 문법에서 <> 이것으로 타입을 선언해줍니다. 그니까, 뭐로 이루어졌는지를 알려주는거죠!
List 이긴 한데, 일반 리스트가 아니라 맵으로 이뤄진 리스트고, 그 맵은 또 String 타입의 key 와 dynamic 타입의 value 를 가진다는 뜻이에요!
(dynamic은 '모든 것' 이라고 생각하시면 됩니다.)
이렇게! question_list.dart 에 이 리스트 하나만 넣어줄게요.
이렇게 보이면 됩니다! 왼쪽에 초록색이 되거나 question_list.dart 가 파란색이 아니더라도 걱정마세요. 현재는 변화 없는게 정상입니다! 😉
그리고!
quiz_screen.dart 로 이동해볼게요. 💨
일단은 이해가 안 되어도 따라 해보세요!
우리의 questionList 의 첫 번째 문항을 사용해보겠습니다.
첫 번째는 컴퓨터에게 0번이라고 했었죠?
QuizScreen 의 Column 값 중에서 우리가 질문으로 주었던 Text 위젯을 바꿔보겠습니다.
Text("질문 입니다"),
를 이렇게 바꿔줄게요!
Text(questionList[0]["questionText"]),
이렇게 바꿔주었습니다.
우리가 다른 파일에서 썼던 questionList 를 불러오기 해서 (엔터 치면 자동으로 불러오기 됨),
그 중 첫 번째 항목(0번째) 의,
'questionText' 라는 key 값을 가지는 value 값을 가져온 것입니다!
저에게는 그게 '평화로운 휴일!\n간만에 찾은 자유시간,\n당신은 무엇을 하시겠습니까?'
라는 값이 되었어요.
한 번 Run ▶️ 눌러볼까요?
여러분의 첫 번째 questionText 가 보이면 성공입니다!
대박!!
성공적으로 화면이 보여요!
마찬가지로 ElevatedButton 의 child: 값에 이렇게 넣어줄게요!
일단은 첫 번째 버튼 값만 바꿔볼게요.
ElevatedButton(
onPressed: () {},
child: Text(questionList[0]["answers"][0]["text"]),
),
다시 Run 해볼까요?
오!! 버튼도 성공적으로 바뀌었어요! 🥳
이제 다음 시간을 위한 준비가 다 되었네요.
이번 파트가 길어서 힘들었을 텐데, 끝까지 수고 많으셨습니다!! 😎
그럼, 다음 시간에 봐요 🥰
quiz_screen.dart
import 'package:flutter/material.dart';
import 'package:personal_quiz/question_list.dart';
class QuizScreen extends StatelessWidget {
const QuizScreen({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
const SizedBox(height: 100),
Text(questionList[0]["questionText"]),
const SizedBox(height: 150),
ElevatedButton(
onPressed: () {},
child: Text(questionList[0]["answers"][0]["text"]),
),
ElevatedButton(onPressed: () {}, child: Text("대답 2")),
ElevatedButton(onPressed: () {}, child: Text("대답 3")),
ElevatedButton(onPressed: () {}, child: Text("대답 4")),
],
),
);
}
}