Menu
murmur blog
  • About me
  • Flutter
murmur blog

Flutter 레이아웃

Posted on 2019년 10월 31일2019년 11월 5일 by JH Y
Table of Content
본 문서는 flutter 에서 제공하는 공식 문서를 참고하여 작성 했습니다.

[Flutter 레이아웃]

Flutter 레이아웃 메커니즘의 핵심은 위젯입니다. Flutter에서는 거의 모든 것이 위젯이고 심지어 레이아웃도 위젯으로 구성 합니다. Flutter 앱 내에서 볼 수 있는 이미지, 아이콘, 글자 모두 위젯입니다.
또한 row, column, grid 같이 볼 수 없는 레이아웃 위젯들도 있는데요, 이들은 보이는 위젯들을 제어하고 정렬합니다.

여러 위젯을 복합적으로 사용해서 레이아웃을 구성 합니다. 예를들어 아래 첫번째 스크린샷 이미지는 라벨이 있는 아이콘 3개를 보여줍니다.

Sample layout

두 번째 스크린샷은 시각적으로 레이아웃을 표시하고 있습니다.

Tip: 이 튜토리얼 내 대부분의 스크린샷은 debugPaintSizeEnabled가 
true로 설정된 상태로 표시되므로 시각적 레이아웃을 볼 수 있습니다.  
더 많은 정보는 Debugging layout issues visually를 참고 하세요.

다음은 위 UI에 대한 widget tree입니다.

대부분이 예상대로 보이지만, (분홍색으로 표시된)container가 뭔지 궁금하실겁니다.
Container는 자식 위젯들을 커스터마이징할 수 있는 위젯 인데요. padding, margin, border 또는 배경색(background)을 추가하고 싶을 때 Container를 사용할 수 있습니다.

이 예제에서, 각 Text 위젯은 margin추가를 위해 Container 안에 배치되었고, 마찬가지로 Row 전체를 감싸는 padding을 추가하기 위해 Container 안에 배치되었습니다.

이 예제의 나머지 UI는 속성에 의해 제어됩니다. Icon의 색상은 color 속성을 이용해 설정했습니다. 폰트, 색상, 굵기 등을 설정하기 위해서는 Text.style 속성을 사용합니다.
Column과 Row에는 자식들을 세로 혹은 가로로 정렬하는 방법과 자식들이 차지해야 하는 공간을 지정할 수 있는 속성이 있습니다.

[widget 배치]

이번에는 flutter에서 간단한 위젯을 어떻게 화면에 출력 하는지 알아 보겠습니다.

Flutter에서
text, icon, image 와 같은 widget을 화면에 배치하는것은 어렵지 않습니다.

1) layout widget 선택

여러가지 layout widget 중에 이번 예제에서는 Center widget을 써보겠습니다.
Center widget은 수평,수직 기준 가운데에 자식 widget을 배치 합니다.

2) visible widget 생성

Text widget 사용법.

Text('Hello World'),

Image widget 사용법

Image.asset(
  'images/lake.jpg',
  fit: BoxFit.cover,
),

Icon widget 사용법

Icon(
  Icons.star,
  color: Colors.red[500],
),

3) visible widget(화면에 보암)을 layout widget(화면에 보이지 않음)에 추가하기.

모든 layout widget은 child 또는 children 속성을 갖습니다.
본 글에서는 child 또는 children 속성을 자식 으로 표현하기도 했습니다.

Center 나 Container 는 child 속성을 갖고, Row, Column, ListView, Stack 위젯은 children 속성을 갖습니다.

Text widget 을 Center widget에 넣어 보겠습니다:

Center(
  child: Text('Hello World'),
),

4) layout widget 을 page에 추가하기.

Flutter app은 그 자체로도 widget 입니다. 그리고 대부분의 widget은 build() method를 갖고 있습니다. build() method는 화면을 그리는 역할을 합니다.

■ Material apps

Material app 에서는 Scaffold widget을 사용할 수 있습니다.
Scaffold widget은 많은 속성을 제공 합니다.
default banner, background color,추가적인 drawer를 위한 API, snack bars,bottom sheet 같은 것들 입니다. 차차로 이런 속성들을 하나씩 쓰게 될 것입니다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter layout demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter layout demo'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}
참고: Material library 는 widget을 Material Design 원칙에 따라 구성 합니다.  
UI를 디자인 할때 스탠다드 widget library 에서 사용할 수도 있고 또는  
Material library에 있는 widget을 쓸 수도 있습니다.  
물론 두개를 섞어 쓸 수도 있습니다. 그리고 직접 widget을 만들 수도 있습니다. 

■ Non-Material apps

non-Material app 의 Center widget을 build() method 에서 사용할 수 있습니다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: Colors.white),
      child: Center(
        child: Text(
          'Hello World',
          textDirection: TextDirection.ltr,
          style: TextStyle(
            fontSize: 32,
            color: Colors.black87,
          ),
        ),
      ),
    );
  }
}

기본적으로 non-Material app 은 AppBar, title, background
color 같은 속성을 지원하지 않습니다. 만약 이런 속성을 사용하고 싶다면 직접 만들어야 합니다. 위 예제 앱은 background color 를 흰색으로 바꾸고 글자를 회색으로 변경합니다.

여기까지 입니다. 앱을 실행하면 Hellow world 메시지를 보실 수 있을 것입니다.

App source code:
– Material app
– Non-Material app


[Multiple widget의 수직 또는 수평 배치]

가장 대표적인 레이아웃 패턴은 위젯을 수평 또는 수직 배치 하는 것입니다.
Row, Column을 이용하여 수평,수직 배치 할 수 있습니다.

Row, Column widget 특징
  * Row, Column은 가장 대표적인 layout 패턴 입니다. 
  * Row, Column 은 children 속성으로 widget list를 갖습니다. 
  * children 속성으로 Row, Column 이 또 올 수도 있고, 다른 widget 역시 올 수 있습니다. 
  * children을 어떻게 정렬 할지 조정 할 수 있습니다. 
  * 특정 자식 widget을 늘리거나 제한 할 수 있습니다. 
  * 자식 widget이 Row 또는 Column 의 가용공간을 어떻게 사용할지 정할 수 있습니다. 

수평 또는 수직 레이아웃을 만들기 위해 Row, Column widget을 사용 합니다.
Row 또는 Column widget의 자식으로 Row, Column 이 올 수도 있습니다.
아래 예제를 통해 Row, Column widget 의 자식으로 Row,Column 을 사용하는 방법을 알아보겠습니다.

예제의 layout은 Row로 크게 구조를 잡습니다. Row는 두개의 자식을 갖습니다. 첫번째로 column 을 갖고, 두번째로 image를 갖습니다.

첫번째 왼쪽 column 의 자식으로 row와 column을 갖습니다.
첫번째 왼쪽 column 레이아웃을 자세히 보겠습니다.

조금뒤에 Pavlova’s layout 예제 Nesting rows and columns
를 통해 자세히 알아 보겠습니다.

참고:
Row 와 Column은 수평, 수직 레이아웃을 만들기 위한 기본 widget입니다.  
이러한 low-level widget은 다양하게 커스트마이징을 할 수 있습니다.  
Flutter는 좀 더 높은 레벨의 widget도 제공 합니다.  
이런 widget을 잘 응용해서 사용하면 좀 더 편하게 app을 만들 수 있습니다.
예를 들어 ListTile은 trailing icon 과 세 줄의 text 를 만들어 줍니다. 
ListView는 가용 공간내에 수직의 레이아웃을 만들고 scrolling을 자동으로 구성해줍니다. 
이후에 좀더 다양한 layout widget을 알아볼 것입니다. 
더보기: Common layout widgets

1)widget 정렬

row 나 column 이 자식 widget을 어떻게 정렬 할지 mainAxisAlignment 와 crossAxisAlignment 속성으로 정의할 수 있습니다.
row widget 에 mainAxis 는 수평을 결정하고,crossAxis는 수직의 정렬을 결정 합니다.
column widget에 mainAxis 는 수직을 결정하고,crossAxis는 수평의 정렬을 결정 합니다.

MainAxisAlignment 와
CrossAxisAlignment 는 많은 속성을 제공 합니다. 링크를 통해 가시면 자세한 속성을 보실 수 있습니다.

참고:
이미지를 프로젝트에 추가할때, pubsec 파일을 수정해야 합니다. 이번 예제에서는 
Image.asset을 이용해 이미지를 출력 할 것이므로 이미지를 pubsec 파일에 추가 해줘야 합니다. 
만약, 이미지를 online 에 있는것을 쓴다면 따로 pubsec을 수정하지 않고도 사용 가능 합니다.
Adding Assets and Images in Flutter 을 참고 하세요.

아래 예제의 세가지 이미지는 100 pixel 입니다.
전체 screen size는 300 pixel 이상입니다. main axis 의 alignment 속성을 spaceEvenly 로 주면 이미지가 공간을 동일하게 나눠 가집니다.
Row widget 예제를 보겠습니다.

**App source:** [row_column]

Column 역시 동일하게 동작 합니다.

**App source:** [row_column]

2)widget 사이즈

layout이 device의 화면 크기에 비해 지나치게 크면 노란배경에 검정선이 그어진 패턴이 나타납니다.
예제 소스

이런경우 Expanded를 이용하여 화면크기에 맞출 수 있습니다.
아래는 Expanded 위젯을 사용한 예제 입니다.

**App source:** [sizing]

만약 특정 위젯이 주변 위젯보다 더 넓은 범위를 차지하게 하고 싶다면 Expanded widget 의 flex 속성을 이용하면 됩니다.
flex 속성의 default 값은 1 입니다. 숫자를 높일 수록 더 넓은 영역을 차지 합니다.
예제를 보겠습니다.

**App source:** sizing

3)Packing widgets

기본적으로 Row와 Column widget은 가능한 영역을 모두 차지 합니다.
이때 자식 widget끼리 붙어 있길 원하면 mainAxisSize값을 MainAxisSize.min 로 설정하면 됩니다.
아래 예제를 보겠습니다.

**App source:** pavlova

4)Nesting rows, column(중첩 Row, Column)

Row와 Column 은 중첩해서 사용 가능 합니다.

빨간 박스로 표시된 부분은 두개의 row로 구성되어 있습니다.
별 5개 와 review가 나오는 row, 아이콘이 나오는 row 이렇게 두개 입니다.
아이콘이 나오는 두번째 row는 세개의 column으로 구성 되어 있습니다.

첫번째 row (별이 있는 row)의 위젯트리를 보면 아래와 같습니다.

var stars = Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.black),
    Icon(Icons.star, color: Colors.black),
  ],
);

final ratings = Container(
  padding: EdgeInsets.all(20),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      stars,
      Text(
        '170 Reviews',
        style: TextStyle(
          color: Colors.black,
          fontWeight: FontWeight.w800,
          fontFamily: 'Roboto',
          letterSpacing: 0.5,
          fontSize: 20,
        ),
      ),
    ],
  ),
);
참고: 중첩된 layout code로 인한 혼란을 줄이려면, UI widget 조각들을 그룹지어 변수와 함수로 구성 하는게 좋습니다. 

아이콘이 나오는 두번째 row를 보겠습니다. 이 row는 3개의 column을 자식 widget 으로 갖습니다.
각 column은 하나의 icon과 두 개의 text 로 구성되어 있습니다.
widget tree를 보면 아래와 같습니다.

iconList 변수에 icon row(icon 세개가 나오는 row)를 정의 했습니다.

final descTextStyle = TextStyle(
  color: Colors.black,
  fontWeight: FontWeight.w800,
  fontFamily: 'Roboto',
  letterSpacing: 0.5,
  fontSize: 18,
  height: 2,
);

// DefaultTextStyle.merge() 는 default text를 지정할 수 있습니다. 
// style은 자식위젯으로 상속 됩니다. 
final iconList = DefaultTextStyle.merge(
  style: descTextStyle,
  child: Container(
    padding: EdgeInsets.all(20),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Column(
          children: [
            Icon(Icons.kitchen, color: Colors.green[500]),
            Text('PREP:'),
            Text('25 min'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.timer, color: Colors.green[500]),
            Text('COOK:'),
            Text('1 hr'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.restaurant, color: Colors.green[500]),
            Text('FEEDS:'),
            Text('4-6'),
          ],
        ),
      ],
    ),
  ),
);

leftColumn 변수는 rating과 icon row를 정의 하고, title과 text도 정의 합니다.
(왼쪽 Column 전체를 정의 합니다.)

final leftColumn = Container(
  padding: EdgeInsets.fromLTRB(20, 30, 20, 20),
  child: Column(
    children: [
      titleText,
      subTitle,
      ratings,
      iconList,
    ],
  ),
);

left column(이미지 왼쪽 컬럼)은 Container 의 자식 widget 이 되고 Container는 column의 width 를 440으로지정 합니다.
최종적으로, 전체 row는 left column 과 image를 포함한 Card widget 내에 위치하게 됩니다.

Pavlova image(예제의 오른쪽 이미지)는 Pixabay(웹사이트)에서 가져 왔습니다.
network 상의 이미지는 Image.network() 를 통해 가져올 수 있습니다.
하지만, 이번 예제에서는 image를 project 내에 직접 저장하여 사용할 것입니다.
이를 위해 pubspec file을 수정해야 합니다.
project에 포함된 image는 Images.asset() 을 이용해 사용할 수 있습니다.
더 많은 정보는 Adding assets and images를 참고 하세요.

body: Center(
  child: Container(
    margin: EdgeInsets.fromLTRB(0, 40, 0, 30),
    height: 600,
    child: Card(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            width: 440,
            child: leftColumn,
          ),
          mainImage,
        ],
      ),
    ),
  ),
),
참고: Pavlova 예제는 큰 화면에도 적절하게 보여집니다.  
시뮬레이터에서 큰 화면을 가진 device로 변경해서도 테스트 해보세요.  
또한 화면을 회전 시켜도 적절하게 보여집니다.  **Hardware > Rotate** 메뉴를 이용해 가로모드 화면에서 테스트 해보세요.
**Window > Scale** 을 이용하면 시뮬레이터 window 크기를 변경 할 수도 있습니다.
( 여러가지 화면 크기에 맞춰서 widget이 적절히 변경되는 것을 확인 할 수 있을 것입니다. )

App source: pavlova


[일반적인 layout widgets]

Flutter는 풍부한 layout widget library를 갖고 있습니다.
몇가지 대표적인 것을 소개하겠습니다.
Widget catalog 를 이용하거나,
API reference docs 에서 검색을 하시면 편합니다.
API docs은 적절한 widget을 추천 해주기도 하니 참고 하세요.

아래 소개 되는 widget은 widgets library의 standard widget과 Material library의 widget 입니다. widgets library는 어느 app이든 사용가능하지만 Material library는 Material app에서만 사용 가능 합니다.

1) standard widgets

  • Container: padding, margins, borders, background color, 기타 style을 적용 가능 합니다.
  • GridView: widget 을 스크롤 가능한 grid 모양으로 배치 합니다.
  • ListView: widget 을 스크롤 가능한 list 로 배치 합니다.
  • Stack: widget을 순차적으로 쌓아가면서 표시 합니다.

2) Material widgets

  • Card: 관련된 정보를 box 안에 표시 합니다.
  • ListTile: 최대 3줄의 text를 표시하고, trailing icon 을 넣을 수 있습니다.

3) Container

많은 레이아웃에서 Container의 padding, border, margin등의 style을 통해서 widget간에 공간을 줍니다. 또한 Container를 이용하면 전체 화면의 background color 나 image 를 변경 할 수도 있습니다.

Summary (Container)

* padding, margin, border 사용 가능
* background color 또는 image 변경 가능
* 하나의 child widget을 갖는다. 다만, child widget으로 Row, Column 등 다수의 자식을 갖는 wid이 올 수 있다.

Examples (Container)

이 예제는 하나의 column 안에 두개의 row가 있고 각 row는 2 개의 이미지를 갖습니다.
Container는 background color를 밝은회색으로 변경 합니다.

Container는 둥근 테두리(rounded border) 와 margin 을 각 이미지에 부여 합니다.

Widget _buildDecoratedImage(int imageIndex) => Expanded(
  child: Container(
    decoration: BoxDecoration(
      border: Border.all(width: 10, color: Colors.black38),
      borderRadius: const BorderRadius.all(const Radius.circular(8)),
    ),
    margin: const EdgeInsets.all(4),
    child: Image.asset('images/pic$imageIndex.jpg'),
  ),
);

Widget _buildImageRow(int imageIndex) => Row(
  children: [
    _buildDecoratedImage(imageIndex),
    _buildDecoratedImage(imageIndex + 1),
  ],
);

더 많은 Container 예제는 tutorial 또는 Flutter Gallery를 참고 하세요.

App source: container


4) GridView

GridView 는 표처럼 위젯을 가로,세로로 정렬해서 배치합니다. GridView 는 두가지 기본 list를 제공 하고, 원한다면 직접 custom 할 수도 있습니다.
GridView는 scroll을 자동 제공 합니다.

Summary (GridView)

  • grid 형태로 widget 배치
  • scrolling지원
  • 직접 custom grid를 만들던지,아래 제공되는 두가지 속성을 사용 할 수 있습니다.:
    • GridView.count 지정된 개수 만큼의 column 을 제공 합니다.
    • GridView.extent 타일의 최대 width를 지정 합니다.
  • MediaQuery.of(context).orientation 를 사용하여 device의 landscape 나 portrait 을 인지하여 적절히 반응하도록 할 수 있습니다.
참고:
2차원 list를 출력할때 어떤 row 와 column 의 cell인지 중요하면,(예를들어 아보카도 row의 칼로리 column) 
[Table] 또는 [DataTable]를 사용하세요.

Examples (GridView)

GridView.extent 를 이용해 grid width를 150pixel로 제한 합니다.
App source: grid_and_list

GridView.count 를 이용해 portrait mode(세로 모드)일때 2개의 타일이 나오게 적용하고, landscape mode(가로 모드)일때 3개의 타일이 나오도록 합니다. 각 타일의 하단에 있는 이미지 제목은 footer 속성을 이용해 정의 합니다.
Dart code:
grid_list_demo.dart

Widget _buildGrid() => GridView.extent(
    maxCrossAxisExtent: 150,
    padding: const EdgeInsets.all(4),
    mainAxisSpacing: 4,
    crossAxisSpacing: 4,
    children: _buildGridTileList(30));
// 이미지는 pic0.jpg, pic1.jpg...pic29.jpg 이름으로 저장 됩니다. 
// List.generate() 는 object가 반복되는 naming 패턴을 가질 경우 사용 합니다. 
List<Container> _buildGridTileList(int count) => List.generate(
    count, (i) => Container(child: Image.asset('images/pic$i.jpg')));

5) ListView

ListView는
column 형 widget으로 자동으로 scrolling을 지원 합니다.

Summary (ListView)

  • Column형 widget으로 list를 만듭니다.
  • 수평 또는 수직의 layout을 만들 수 있습니다.
  • 자동으로 스크롤링을 만듭니다.
  • Column widget 보다 확장성은 적습니다.

Examples (ListView)

ListView 와 ListTile을 사용하여 영화관과 식당 list를 보여줍니다. Divider는 영화관과 식당 사이를 구분 합니다.
App source: grid_and_list

ListView 를 이용해 Material Design palette의 파란색 그룹 Colors 를 출력 합니다.
Dart code: colors_demo.dart

Widget _buildList() => ListView(
  children: [
    _tile('CineArts at the Empire', '85 W Portal Ave', Icons.theaters),
    _tile('The Castro Theater', '429 Castro St', Icons.theaters),
    _tile('Alamo Drafthouse Cinema', '2550 Mission St', Icons.theaters),
    _tile('Roxie Theater', '3117 16th St', Icons.theaters),
    _tile('United Artists Stonestown Twin', '501 Buckingham Way',
        Icons.theaters),
    _tile('AMC Metreon 16', '135 4th St #3000', Icons.theaters),
    Divider(),
    _tile('K\'s Kitchen', '757 Monterey Blvd', Icons.restaurant),
    _tile('Emmy\'s Restaurant', '1923 Ocean Ave', Icons.restaurant),
    _tile(
        'Chaiya Thai Restaurant', '272 Claremont Blvd', Icons.restaurant),
    _tile('La Ciccia', '291 30th St', Icons.restaurant),
  ],
);

ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
  title: Text(title,
      style: TextStyle(
        fontWeight: FontWeight.w500,
        fontSize: 20,
      )),
  subtitle: Text(subtitle),
  leading: Icon(
    icon,
    color: Colors.blue[500],
  ),
);

6) Stack

Stack 은 base widget 위에 widget을 중첩해서 출력 합니다. Stack의 자식 widget은 base widget을 완전히 덮을 수도 있고 일부만 덮을 수도 있습니다.

Summary (Stack)

  • 다른 widget 위에 widget을 배치 합니다.
  • 첫번째 widget이 base widget 입니다. 그 위로 다른 widget 이 배치 됩니다.
  • Stack 은 scroll 되지 않습니다.
  • box를 넘는 자식 widget을 자를 수 있습니다.

Examples (Stack)

Stack을 이용해 CircleAvatar위에 Container widget을 출력 합니다. Container widget은 Text를 반투명 검정 배경에 보여주는 역할을 합니다.
Stack 은 alignment 속성과 Alignment를 이용해 text의 위치(offset)를 지정 합니다.

App source: card_and_stack

Stack을 이용해 image 상단에 그라디언트를 넣습니다. 이 그라디언트를 통해 toolbar 의 icon이 iamge와 구분됩니다.
Dart code: contacts_demo.dart

Widget _buildStack() => Stack(
  alignment: const Alignment(0.6, 0.6),
  children: [
    CircleAvatar(
      backgroundImage: AssetImage('images/pic.jpg'),
      radius: 100,
    ),
    Container(
      decoration: BoxDecoration(
        color: Colors.black45,
      ),
      child: Text(
        'Mia B',
        style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
          color: Colors.white,
        ),
      ),
    ),
  ],
);

7) Card

Material library 의 Card 는 여러 종류의 정보를 보여줄 수 있고, 다른 widget들과 함께 쓰일 수 있습니다. 하지만 주로 ListTile 과 쓰입니다.
Card는 child 를 하나만 갖지만, column, row, list, grid 같은 Multiple 자식을 갖는 widget을 child로 가질 수 있습니다.
Card는 size를 0 X 0 으로 줄일 수 있습니다. SizedBox 를 이용해 card size를 제어 할 수 있습니다.

Flutter 에서 Card widget은 모서리를 살짝 둥글게 보여주고, 그림자가 있습니다.
Card의 elevation 속성을 변경하여 그림자 효과를 제어 할 수 있습니다.
elevation 속성을 24로 설정하면, 표면에서 더 멀어지고 그림자가 분산됩니다.
Flutter 에서 지원하는 elevation 값은 Elevation 페이지에서 확인 할 수 있습니다. 만약 지원하지 않는 값을 주면 그림자 효과가 사라집니다.

Summary (Card)

  • Material card 입니다.
  • 관련된 정보를 표현하는데 사용합니다.
  • 자식을 하나만 갖지만, 멀티플 자식을 갖는 위젯을 자식으로 가질 수 있습니다.
  • 둥근 테두리와 그림자를 보여줍니다.
  • 스크롤 되지 않습니다.
  • Material library 의 widget 입니다.

Examples (Card)

Card에 3 개의 ListTiles 이 있고 SizedBox로 사이즈를 줍니다.Divider 로 첫번째와 두번째 ListTiles을 구분 합니다.

App source: card_and_stack

Card에 image 와 text 가 있습니다..

Dart code: cards_demo.dart

Widget _buildCard() => SizedBox(
  height: 210,
  child: Card(
    child: Column(
      children: [
        ListTile(
          title: Text('1625 Main Street',
              style: TextStyle(fontWeight: FontWeight.w500)),
          subtitle: Text('My City, CA 99984'),
          leading: Icon(
            Icons.restaurant_menu,
            color: Colors.blue[500],
          ),
        ),
        Divider(),
        ListTile(
          title: Text('(408) 555-1212',
              style: TextStyle(fontWeight: FontWeight.w500)),
          leading: Icon(
            Icons.contact_phone,
            color: Colors.blue[500],
          ),
        ),
        ListTile(
          title: Text('costa@example.com'),
          leading: Icon(
            Icons.contact_mail,
            color: Colors.blue[500],
          ),
        ),
      ],
    ),
  ),
);

8) ListTile

ListTile 은 Material library 의 row 형 widget 입니다.
3줄의 text를 표현할 수 있고 trailing icon을 넣을 수 있습니다.
ListTile 은 Card나 ListView 의 child로 많이 사용됩니다. 물론 다른 widget에서도 사용할 수 있습니다.

Summary (ListTile)

  • row 형 widget 이고, 3줄의 text를 표현할 수 있고 trailing icon을 넣을 수 있습니다.
  • Row보다 확장성이 적습니다. 하지만 더 사용하기 쉽습니다.
  • Material library 의 widget 입니다.

Examples (ListTile)

Card는 3개의 ListTiles을 포함 합니다.

App source: card_and_stack

ListTile 을 이용해 3개의 drop down button type 의 list를 만듭니다.
Dart code: buttons_demo.dart


여기까지 기본적인 레이아웃 widget을 알아봤습니다.

더보기

이 글 공유하기:

  • 인쇄하기 (새 창에서 열림)
  • 페이스북에 공유하려면 클릭하세요. (새 창에서 열림)
  • 트위터로 공유하기 (새 창에서 열림)
  • LinkedIn으로 공유하기 (새 창에서 열림)
  • 구글 +1에서 공유하려면 클릭하세요 (새 창에서 열림)
  • 친구에게 전자우편으로 보내기 (새 창에서 열림)

관련

app개발 flutter layout mobile 개발 widget 레이아웃 위젯 플러터 플루터
Flutter

답글 남기기 응답 취소

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.

카테고리

  • a-Tech
  • Aix
  • ETC
  • Flutter
  • Food
  • K_culture
  • Media
  • Power system
  • Storage

그 밖의 기능

  • 로그인
  • 글 RSS
  • 댓글 RSS
  • WordPress.org

최근 글

  • Box Constraint
  • Flutter responsive UI
  • Flutter 레이아웃
  • Flutter widget 소개
  • Write your first Flutter app, part 2
©2023 murmur blog | Powered by WordPress & Superb Themes
loading 취소
글이 전송되지 않았습니다. 이메일 주소를 확인하세요!
이메일 확인에 실패했습니다. 다시 시도하세요
죄송합니다. 귀하의 블로그에서 이메일로 글을 공유할 수 없습니다.