> Frontend/Flutter

Flutter_07.Quiz App04_Map & For loops (마무리)

Janku 2023. 4. 26. 20:43

0. 

  - Map & Forr Loops. (Skipped to ep.80)

  - Type Casting.

  - Combining Columns and Rows.

  - Expanded 

  - SingleChildScrollView를 사용해 scroll  

  

 

1.  For Loops.

import 'package:flutter/material.dart';

import 'package:basic101_01/components/data/questions.dart';
import 'package:basic101_01/components/questions_summary.dart';

class ResultsScreen extends StatelessWidget {
  const ResultsScreen({
    super.key,
    required this.chosenAnswers,
  });

  final List<String> chosenAnswers;

  List<Map<String, Object>> getSummaryData() {
    final List<Map<String, Object>> summary = [];
    // For loops
    for (var i = 0; i < chosenAnswers.length; i++) {
      summary.add({
        'question_index': i,
        'question': questions[i].text,
        'correct_answer': questions[i].answers[0],
        'user_answer': chosenAnswers[i]
      });
    }
    return summary;
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      child: Container(
        margin: const EdgeInsets.all(40),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('You answered X out of Y questions correctly!'),
            const SizedBox(
              height: 30,
            ),
            QuestionsSummary(getSummaryData()),
            const SizedBox(
              height: 30,
            ),
            TextButton(
              onPressed: () {},
              child: const Text('Restart Quiz!'),
            )
          ],
        ),
      ),
    );
  }
}

 

 

 

2. Map을 사용해서 QuestionsSummary 생성

import 'package:flutter/material.dart';

class QuestionsSummary extends StatelessWidget {
  const QuestionsSummary(this.summaryData, {super.key});

  final List<Map<String, Object>> summaryData;

  @override
  Widget build(BuildContext context) {
    return Column(
      // Maps returns a Iterable which cannot assigned to Widget
      // Needs to mutate List by using toList();
      children: summaryData.map((data) {
        return Row(children: [
          Text(((data['question_index'] as int) + 1).toString()),
          // use Type-Casting
          Column(
            children: [
              Text(data['question'] as String),
              const SizedBox(height: 5),
              Text(data['user_answer'] as String),
              Text(data['correct_answer'] as String),
            ],
          ),
        ]);
      }).toList(),
    );
  }
}

 

   - 중요: Map은 Iterable 을 return 해주며, 해당 값은 Widget으로 바로 사용이 안되고, toList()를 사용해서 변환후 사용. 

 

3.  Expanded 추가 

 

Expanded(
  // Expanded widgets allow it child to take the available space along the flex widgets main axis.
  // Flex Widget: Row or Column widget that i put into expand
  // THis restricted to the width of a row.
  child: Column(
    children: [
      Text(data['question'] as String),
      const SizedBox(height: 5),
      Text(data['user_answer'] as String),
      Text(data['correct_answer'] as String),
    ],
  ),
),

   - Expanded 는 Row/ Column의 자식으로 사용 가능하며, 자식들이 화면을 넘친 경우, 부모의 Width/ Height 로 제한하게 한다.

 

Without Expanded With Expanded
With Extended

 

 

4. Where 를 사용해 filter같이 사용 (JS Filter와 비슷)

 

final summaryData = getSummaryData();
final numTotalQuestions = questions.length;
final numCorrectQuestions = summaryData.where((data) {
  return data['correct_answer'] == data['user_answer'];
}).length;

 

Text(
  'You answered $numCorrectQuestions out of $numTotalQuestions questions correctly!',
),

 

5. SingleChildScrollView

   -주어진 SizedBox의 height가 낮아, 왼쪽과 같이 overflow가 발생하면, child박스를 SingleChildScrollView로 감싸, scroll화 한다

return SizedBox(
  height: 300,
  child: SingleChildScrollView(
without SingleChildScrollView with SingleChildScrollView