본문 바로가기
Development/Flutter

Flutter - 4. Widget? Row, Column

by du.it.ddu 2021. 1. 11.
반응형

이전 포스팅에서 Text, Image, Button, Container에 대해 알아보았다.
Container는 하나의 child를 가질 수 있어서 하나의 Text, Image, Button만을 표현할 수 있었다.
하지만 앱은 많은 Text, Image, Button들을 조합하여 개발된다.

이번 포스팅에서 Row, Column을 활용하여 다양한 구성요소로 화면을 구현 해 보자.


1. Row vs Column

Row는 행 방향으로 Widget을 나열하며, Column은 열 방향으로 Widget을 나열한다.
각각의 생성자를 확인해보자.

Row
Column

생성자 파라미터의 구성을 보면 거의 동일한 것을 알 수 있다.
이 포스팅에서 다룰 파라미터는 세 가지다.

  • MainAxisAlignment mainAxisAlignment
  • CrossAxisAlignment crossAxisAlignment
  • List<Widget> children

Row, Column은 List<Widget> children 파라미터를 보면 알 수 있듯, Widget의 리스트를 받는다. 많은 Widget들을 담을 수 있다는 뜻이다.

mainAxisAlignment는 Row, Column이 Widget들을 행 또는 열 방향으로 그려나가면서 적용할 정렬 규칙이다. Row라면 행 방향으로 적용되며, Column이라면 열 방향으로 적용된다. "Main" 의 의미를 잘 생각해보자.

mainAxisAlignment이 Row 또는 Column의 주된 방향에 대한 정렬 규칙이라면, crossAxisAlignment는 주된 방향과 엇갈리는, 반대의 정렬 방향을 의미한다.

flutter.dev/docs/codelabs/layout-basics?source=post_page-----dd21d9e883c2----------------------#axis-size-and-alignment

 

Basic Flutter layout concepts

A codelab that teaches basic Flutter layout concepts through DartPad examples and exercises.

flutter.dev

정렬에 관한 내용은 위 링크에서 전부 확인할 수 있다. 그 외에도 Flutter의 Layout에 대한 공식 문서이니 참고하면 좋겠다.

이제 가벼운 내용으로 코드를 통해 알아보자.


2. Row

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: SafeArea(
        child: Scaffold(
          body: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Text("This is Text!!"),
              Image(image: AssetImage("images/flutter_logo.png"), width: 100, height: 50,),
              RaisedButton(
                child: Text("This is RaisedButton!!"),
                onPressed: () {},
              )
            ],
          ),
        ),
      )
    );
  }
}

위에서 SafeArea는 앱의 노치 등의 영역을 침범하지 않게 해 준다.


Scaffold는 AppBar, Drawer, BottomNavigationBar 등의 앱 구성요소들을 파라미터로 받을 수 있고 body를 통해 앱을 구성할 수 있는 Widget이다. Scaffold는 추후 따로 정리 할 계획이다.

위 코드를 실행하면 위와 같은 결과를 확인할 수 있다.
행(가로) 방향으로 Text, Image, Button 위젯을 순서대로 나타내 주었다.


3. Column

Row에서 사용한 코드를 그대로 사용하고 Row에서 Coulmn으로만 변경하겠다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ...
      home: SafeArea(
        child: Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
               ...
              )
            ],
          ),
        ),
      )
    );
  }
}

Row에서 Coulmn으로만 변경되었을 뿐 인데 세로 방향으로 배치하는 것으로 바뀌었다.
Row와 Column은 컨셉은 동일하고 배치 방향만 다를 뿐이다.


4. Row, Column의 조합

Row와 Column을 하나만 써서는 사실 다양한 화면을 구성하기는 쉽지 않다.
하나의 행 또는 열만을 구성하기 때문이다.

하지만 Row와 Column또한 Widget이므로 Row, Column 내부에서 Row, Column을 사용해줄 수 있다.

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ...
      home: SafeArea(
        child: Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              _myRow(),
              _myRow(),
              _myRow(),
              _myRow()
            ],
          ),
        ),
      )
    );
  }

  Widget _myRow() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text("This is Text!!"),
        Image(image: AssetImage("images/flutter_logo.png"), width: 100, height: 50,),
        RaisedButton(
          child: Text("This is RaisedButton!!"),
          onPressed: () {},
        )
      ],
    );
  }
}

위와 같은 방식으로 Coulmn 내부에 여러 개의 Row를 포함시켜 위와 같은 형태의 UI가 가능하다.
물론 한 Row에 다양한 구성도 가능하다.

반대로 Row안에 다양한 Column을 넣는 것 또한 가능하다.


Row, Column은 Row와 Column을 포함한 다양한 Widget을 조합하여 더욱 풍부한 UI를 구현하게 해 준다.

하지만 이번 포스팅처럼 동일한 UI를 가진 Widget들이 계속 쌓일 때, 화면을 넘어가면 어떻게 될까?
스크롤이 가능하게 하는 Widget이 있다면 모를까, Row, Column 자체로는 스크롤이 되지 않고 넘어간 것을 처리할 수 없다.

다음 포스팅은 이러한 동일한 UI를 가진 Widget을 리스트 형식으로 쌓을 수 있는 Widget에 대해 소개 할 것이다.

반응형