class ResultScreen extends StatelessWidget {
const ResultScreen({super.key, required this.chosenAnswers});
final List<String> chosenAnswers;
List<Map<String, Object>> getSummaryData() {
final List<Map<String, Object>> summary = [];
for (var i = 0; i < chosenAnswers.length; i++) {
summary.add({
'question_idx':i,
'question':questions[i].text,
'correct_answer':questions[i].answers[0],
'user_answer':chosenAnswers[i]
});
}
return summary;
}
Widget build(context) {
return SizedBox(
...
final numbers = [5, 6];
final myList = [
1,
2,
...numbers.map((n) {
return n * 2;
}) // adds 10 and 12
];
또한 위 코드와 같이 spread operation + .map을 for문으로 갈아치울 수 있다.
그리고 Widget에서 사용된다면 반드시 마지막에 .toList() 메서드도 함께 와야한다.
key, value로 이루어져있는 구조로 각각 타입을 선언하고 물론 중첩하여 사용도 가능하다.
위 코드에서는 key값을 String으로 받고 value값은 어떤 값이든 올 수 있도록 Object 타입으로 지정하였다.
import 'package:flutter/material.dart';
class QuestionsSummary extends StatelessWidget {
const QuestionsSummary(this.summaryData, {super.key});
final List<Map<String, Object>> summaryData;
Widget build(context) {
return Column(
children: summaryData.map((data) {
return Row(children: [
Text(((data['question'] as int)+1).toString()),
Column(
children: [
Text(data['question'] as String),
const SizedBox(height: 5),
...
],);
}).toList(),
);
}
}
이때 위 코드에서 .map
의 결과값은 iterable한 객체를 반환하는데 문제는 Row는 interable한 객체를 받지 못한다는 것이다.
물론 이는 .toList()
라는 형변환 함수를 통하여 매우 간단하게 해결 가능하다.
as
라는 키워드로 타입 캐스팅을 할 수 있고 이는 주로 Map에서 설정해놓은 타입이 <Object>라면 얘가 .map이나 for loop으로 사용될 때 어떤 타입인지 알 수 없기 때문에 그래서 위 사진을 보면 layout이 다 작살난 것을 확인할 수 있다는 저기 검,노로 라인이 쳐진부분이 바로 flutter가 layout 밖으로 뚫고 나갔다고 경고하고 알려주는 것이다.
이는 Column을 사용할 때 발생하는 현상인데 Column은 무한하게 가로를 그냥 쓴다. 즉, 화면 밖으로 튀어나가는 것이 문제인데 이를 막고자 Expanded가 존재하는 것이다.
이는 Widget 내에서 가용한 최대 너비(부모의 너비)를 차지하여 오류를 방지해준다.
build(context) {
final summaryData = getSummaryData();
final numTotalQuestions = questions.length;
final numCorrectQuestions = summaryData.where((data) {
return data['user_answer'] == data['correct_answer'];
}).length;
return SizedBox(
width: double.infinity,
child: Container(
margin: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('$numTotalQuestions개 중 $numCorrectQuestions개를 맞췄습니다.'),
const SizedBox(height: 30),
QuestionsSummary(summaryData),
const SizedBox(height: 30),
TextButton(onPressed: () {}, child: const Text('문제 다시 풀기!'))
],
),
),
);
}
Widget
.map 과 반대로 새로운 메모리를 참조한다.
.where 안에는 항상 매개변수로 함수가 들어간다.
build(context) {
return SizedBox(
height: 300,
child: SingleChildScrollView(
child: Column(
children: summaryData.map((data) {
return Row(
children: [
Text(((data['question_idx'] as int) + 1).toString()),
Expanded(
child: Column(
children: [
Text(data['question'] as String),
const SizedBox(height: 5),
Text(data['user_answer'] as String),
Text(data['correct_answer'] as String)
],
),
),
],
);
}).toList(),
),
),
);
}
Widget