레이아웃 오류 방지(Expanded)

샤워실의 바보·2024년 2월 26일
0
post-thumbnail
post-custom-banner
import 'package:flutter/material.dart';
import 'package:toonflix/models/webtoon_model.dart';
import 'package:toonflix/services/api_service.dart';

class HomeScreen extends StatelessWidget {
  HomeScreen({super.key});

  final Future<List<WebtoonModel>> webtoons = ApiService.getTodaysToons();

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        elevation: 2,
        backgroundColor: Colors.white,
        foregroundColor: Colors.green,
        title: const Text(
          "어늘의 웹툰",
          style: TextStyle(
            fontSize: 24,
          ),
        ),
      ),
      body: FutureBuilder(
        future: webtoons,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Column(
              children: [
                const SizedBox(
                  height: 50,
                ),
                Expanded(child: makeList(snapshot))
              ],
            );
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      ),
    );
  }

  ListView makeList(AsyncSnapshot<List<WebtoonModel>> snapshot) {
    return ListView.separated(
      scrollDirection: Axis.horizontal,
      itemCount: snapshot.data!.length,
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
      itemBuilder: (context, index) {
        var webtoon = snapshot.data![index];
        return Column(
          children: [
            Container(
              width: 250,
              clipBehavior: Clip.hardEdge,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15),
                boxShadow: [
                  BoxShadow(
                    blurRadius: 15,
                    offset: const Offset(10, 10),
                    color: Colors.black.withOpacity(0.3),
                  )
                ],
              ),
              child: Image.network(webtoon.thumb),
            ),
            const SizedBox(
              height: 10,
            ),
            Text(
              webtoon.title,
              style: const TextStyle(
                fontSize: 22,
              ),
            ),
          ],
        );
      },
      separatorBuilder: (context, index) => const SizedBox(width: 40),
    );
  }
}

Column 위젯은 기본적으로 자식 위젯들을 수직 방향으로 배열합니다. 그 과정에서 Column의 자식들은 기본적으로 Column이 제공하는 공간 내에서만 그려집니다. 만약 자식 위젯이 할당된 공간보다 더 많은 공간을 필요로 한다면, 레이아웃 문제가 발생할 수 있습니다. 예를 들어, ListViewGridView 같은 스크롤 가능한 위젯이 Column의 자식으로 있을 때, 이러한 위젯들은 기본적으로 무한한 높이를 가지려고 시도합니다. Column은 기본적으로 자식에게 제한된 크기를 제공하지 않기 때문에, 이는 레이아웃 문제를 발생시킵니다.

Expanded 위젯은 이러한 문제를 방지하는 데 도움을 줍니다. ExpandedColumn, Row, Flex와 같은 플렉스(flex) 레이아웃 내에서 자식 위젯이 차지할 수 있는 공간을 확장시킵니다. Expanded 위젯을 사용하면 Column의 남은 공간을 차지하도록 자식 위젯을 강제할 수 있으며, 이는 스크롤 가능한 위젯이 무한 높이를 가지려는 문제를 해결합니다. 즉, Expanded 위젯을 사용함으로써 Column의 남은 공간을 채우도록 자식 위젯을 확장하고, 공간 분배를 통해 레이아웃 문제 없이 원하는 대로 UI를 구성할 수 있습니다.

return Column(
  children: [
    const SizedBox(
      height: 50,
    ),
    Expanded(child: makeList(snapshot)) // makeList 함수로 생성된 리스트(예: ListView)가 Column의 남은 공간을 모두 차지하도록 함
  ],
);

위 예제에서 Expanded 위젯 안에 있는 makeList(snapshot)Column에서 남은 공간을 모두 차지하게 됩니다. 이로 인해 makeList 함수로 생성된 스크롤 가능한 리스트가 Column의 남은 공간에 맞춰 적절히 확장되고, 사용자가 스크롤하여 모든 항목을 볼 수 있게 됩니다. 이 방법을 사용하지 않고 스크롤 가능한 위젯을 Column에 직접 추가하면, 위젯이 부모의 제약 조건을 초과하여 에러가 발생할 수 있습니다.

profile
공부하는 개발자
post-custom-banner

0개의 댓글