Flutter for loop, Map, Row

강정우·2023년 5월 15일
0

Flutter&Dart

목록 보기
20/87
post-thumbnail

다른 언어와 똑같음

  • 다만 java에 있는 map 개념을 추가적으로 설명하기위해 예제 코드를 가져옴
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(
    ...
  • 위 코드를 보면 여느 언어와 같은 일반적은 for문인 것을 확인할 수 있다.
final numbers = [5, 6];
final myList = [
  1,
  2,
  ...numbers.map((n) {
    return n * 2; 
  }) // adds 10 and 12
];
  • 또한 위 코드와 같이 spread operation + .map을 for문으로 갈아치울 수 있다.

  • 그리고 Widget에서 사용된다면 반드시 마지막에 .toList() 메서드도 함께 와야한다.

다만 다른 점

  • for in loop를 사용할 때 return값이 Widget이라면 function body를 사용하지 않는다.
    예를 들어 위와 같이 buckets라는 getter 함수가 4개의 List 값을 반환한다고 가정했을 때

생성자 함수를 이용한 데이터 가져오기

  • 위 데이터를 가져와서 function body없이 바로 ChartBar 위젯을 만들어내는 모습이다.

map

  • key, value로 이루어져있는 구조로 각각 타입을 선언하고 물론 중첩하여 사용도 가능하다.

  • 위 코드에서는 key값을 String으로 받고 value값은 어떤 값이든 올 수 있도록 Object 타입으로 지정하였다.

Row

  • 앞서 Column 위젯과 방향만 다르고 거의 동일하다.
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()라는 형변환 함수를 통하여 매우 간단하게 해결 가능하다.

type casting (as)

  • as 라는 키워드로 타입 캐스팅을 할 수 있고 이는 주로 Map에서 설정해놓은 타입이 <Object>라면 얘가 .map이나 for loop으로 사용될 때 어떤 타입인지 알 수 없기 때문에

Expaned

  • 그래서 위 사진을 보면 layout이 다 작살난 것을 확인할 수 있다는 저기 검,노로 라인이 쳐진부분이 바로 flutter가 layout 밖으로 뚫고 나갔다고 경고하고 알려주는 것이다.

  • 이는 Column을 사용할 때 발생하는 현상인데 Column은 무한하게 가로를 그냥 쓴다. 즉, 화면 밖으로 튀어나가는 것이 문제인데 이를 막고자 Expanded가 존재하는 것이다.

  • 이는 Widget 내에서 가용한 최대 너비(부모의 너비)를 차지하여 오류를 방지해준다.

  • 그리고 여기서 말하는 Flex Widget은 본인의 상위 Column 혹은 Row 위젯이다.

.where


  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('문제 다시 풀기!'))
          ],
        ),
      ),
    );
  }
  • .map 과 반대로 새로운 메모리를 참조한다.

  • .where 안에는 항상 매개변수로 함수가 들어간다.

SingleChildScrollView


  Widget 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(),
        ),
      ),
    );
  }
  • 닉값을 하는 위젯이다.
  • 해당 위젯은 1개의 child를 받으며 넘어가는 부분에 있어서 스크롤 처리를 해준다.
  • 또한 편리한 기능은 귀찮게 Padding class를 선언하지 않아도 내부에 padding 속성을 추가할 수 있다는 것이다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글