새로운 강의는 이제 https://memi.dev 에서 진행합니다.
memi가 Vue & Firebase로 직접 만든 새로운 사이트를 소개합니다.

바로가기


Flutter와 Firebase로 Android iOS 둘 다 만들기 2 기본 레이아웃 정렬해보기

2 분 소요

플러터 레이아웃의 핵심인 Container, Row, Column에 대해 알아봅니다.

참고 정보

가장 좋은 학습방법은 역시 공식홈 레이아웃 예입니다.

참고: https://flutter-ko.dev/docs/development/ui/layout

공식홈 레이아웃의 내용대로 따라해 보면서 간단한 설명을 하려합니다.

정렬 기본 개념

정렬은 3가지만 알면 끝입니다.

  • Container
  • Row
  • Column

alt row alt col

이 그림 하나로 사실상 어떤 방식인지 한번에 눈치 챌 수 있습니다.

Row는 수평이고 Column은 수직이란 거죠..

Container는 일부 위젯(Row, Column등)들을 감싸서 여백이나 색상을 조절하는 용도입니다.

위젯의 위젯의 위젯의 …

간단히 코드를 정리해봅니다.

main.dart

import 'package:flutter/material.dart';

void main() { 
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: home()
    );
  }
  Widget home() {
    return Scaffold(
      appBar: AppBar(
        leading: Icon(Icons.menu),
        title: Text('hiru~!!'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.mode_comment),
            onPressed: () {
              print('눌렀어!');
            },              
          ),
          IconButton(
            icon: Icon(Icons.money_off),
            onPressed: () => print('애로우!'),              
          ),
        ],
      ),
      body: body()
    );
  }
  Widget body() {
    return Text('ok??');
  }
}

결과
alt standard

home은 home() 위젯을 Scaffold.body는 body() 위젯을 받게됩니다.

나중에 코드가 많아질 수록 위젯 안으로 들어가면서 탭이 너무 많이 증가하므로 위젯함수로 일부를 나눠봅니다.

이제 body()만 생각하면 되는 것이죠~

Row

먼저 Row 를 채워봅니다.

Widget body() {
  return Row(
    children: <Widget>[
      Text('111'),
      Text('222'),
      Text('333'),
      Text('444'),
      Text('555'),
      Text('666'),
      Text('777'),
      Text('888'),
      Text('999'),
    ]      
  );
}

alt rows1

아무 옵션도 주지 않은 로우는 여백하나 없이 다닥다닥 붙게 되어있습니다.

일반적으로 원하는 모습은 적당한 여백이 들어간 균형감 있는 배치이겠죠..

Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: <Widget>[
    // ...

alt rows2

위와 같은 옵션으로 여백을 줄 수 있습니다.

물론 다른 여러가지 옵션으로 수평뷰에 최적화된 옵션을 쓰면 되겠죠~

참고: https://api.flutter.dev/flutter/widgets/Row-class.html

Column

위의 내용을 아래에 한번 더 써보려면 수직개념인 Column이 필요합니다.

Widget body() {
  return Column(
    children: <Widget>[
      rows(), rows(), rows()
    ],
  );
}
Widget rows() {
  return Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
      Text('111'),
      Text('222'),
      Text('333'),
      Text('444'),
      Text('555'),
      Text('666'),
      Text('777'),
      Text('888'),
      Text('999'),
    ]      
  );
}

alt col

Row와 마찬가지로 다양한 옵션을 children위에 적어두면 여러가지 모양이 나올 수 있겠죠?

Container

Container로 지금까지 한것을 뭉탱이로 박스에 넣고 여백, 색상등을 조절할 때 쓸 수 있습니다.

Widget body() {
  return Container(
    padding: EdgeInsets.all(20),
    decoration: BoxDecoration(
      color: Colors.red,
    ),
    child: cols()
  );
}
Widget cols() {
  return Column(
    children: <Widget>[
      rows(), rows(), rows()
    ],
  );
}
Widget rows() {
  return Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
      Text('111'),
      Text('222'),
      Text('333'),
      Text('444'),
      Text('555'),
      Text('666'),
      Text('777'),
      Text('888'),
      Text('999'),
    ]      
  );
}

alt container

이제 콘테이너 안은 붉은 색이 되고 안에 들어 있는 요소들은 바깥으로 20의 여백을 가지게 됩니다.

그 밖에도 다양한 옵션들이 있으니 적당하게 넣으면 됩니다.

마치며

제가 사실 플러터가 접근성이 좀 떨어진다고 보는 것은.. 디폴트의 미학이 꽝인 느낌입니다.

예제로 작성해본 Row, Column등을 무옵션으로 만들어 보면 정말 추한 것을 알 수 있습니다.

특별한 옵션 없이 Container > Row > Column이 적당한 모양새가 들어가 있다면 좋지 않았을까.. 하는 생각이 듭니다.

물론 모바일앱이라는 손가락으로 제어되어야하기 때문에 큼직한 UI라 실상 특별한 디자인이 많이 들어가지 않기 때문에 옵션은 한두줄 코딩하면 잊어버릴 만한 요소이긴 합니다.

소스코드

https://github.com/fkkmemi/ff

영상

댓글남기기