Layout 2

2022. 6. 3. 00:00Flutter

반응형

Common layout widgets

Standard 위젯과 Material 위젯으로 나눈다.

 

모든 앱은 위젯 라이브러리를 사용할 수 있지만 Material 앱만 Material Components 라이브러리를 사용

 

Standard widgets

 

Container

:위젯에 패딩, 여백, 테두리, 배경색 또는 기타 장식을 추가합니다.

  • 패딩, 여백, 테두리 추가
  • 배경색 또는 이미지 변경
  • 단일 하위 위젯을 포함하고 하위는 행, 열 또는 위젯 트리의 루트일 수 있다.

container_widget.dart

import 'package:flutter/material.dart';

class ContainerWidget extends StatelessWidget {
  const ContainerWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return _buildImageColumn();
  }

  Widget _buildImageColumn() {
    return Container(
      decoration: const BoxDecoration(
        color: Colors.black26,
      ),
      child: Column(
        // textDirection: TextDirection.ltr,
        children: <Widget>[
          _buildImageRow(1),
          _buildImageRow(3),
        ],
      ),
    );
  }

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

  Widget _buildImageRow(int imageIndex) => Row(
    textDirection: TextDirection.ltr,
    children: [
      _buildDecoratedImage(imageIndex),
      _buildDecoratedImage(imageIndex + 1),
    ],
  );
}

 

GridView

:위젯을 스크롤 가능한 그리드로 배치합니다.

gridview_widget.dart

import 'package:flutter/material.dart';

class GridViewWidget extends StatelessWidget {
  const GridViewWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'gridview',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('It is a gridview demo'),
        ),
        body:_buildGrid()
      ),
    );
  }

  Widget _buildGrid() => GridView.extent(
      maxCrossAxisExtent: 100,
      padding: const EdgeInsets.all(4),
      mainAxisSpacing: 4,
      crossAxisSpacing: 4,
      children: _buildGridTileList(4));


      List<Container> _buildGridTileList(int count) => List.generate(
      count, (i) => Container(child: Image.asset('assets/images/dog${i+1}.jpg')));
  }

extent 같은 경우 maxCrossAxisExtent 설정이 중요한데 하나의 cell 이 차지하는 크기라고 생각하면 된다. 

늘리면 하나의 cell 이 많은 크기를 차지 하니 한줄에 표시되는 이미지가 수가 줄고

줄이면 하나의 cell 이 적은 크기를 차지 하니 한줄에 표시되는 이미지가 수가 늘어난다.

 

 

gridview_widget2.dart

import 'package:flutter/material.dart';

class GridViewWidget2 extends StatelessWidget {
  const GridViewWidget2({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'gridview',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('It is a gridview demo'),
        ),
        body:_buildGrid()
      ),
    );
  }

  Widget _buildGrid() => GridView.count(
      crossAxisCount: 2,
      padding: const EdgeInsets.all(4),
      mainAxisSpacing: 4,
      crossAxisSpacing: 4,
      children: _buildGridTileList(4));


      List<Container> _buildGridTileList(int count) => List.generate(
      count, (i) => Container(child: Image.asset('assets/images/dog${i+1}.jpg')));
  }

 

여기서는 crossAxisCount 가 한줄 에 표시되는 이미지의 수 라고 생각하면 된다. 

2 이면 2개 이미지 3 이면 3개 이미지가 표시된다. 

 

 

 

ListView

:위젯을 스크롤 가능한 목록으로 배치합니다.

listview_widget.dart

import 'package:flutter/material.dart';

class ListViewWidget extends StatelessWidget {
  const ListViewWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'lsitview',
      home: Scaffold(
          appBar: AppBar(
            title: const Text('It is a listview demo'),
          ),
          body:_buildList()
      ),
    );
  }

  Widget _buildList() {
    return 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),
        const 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) {
    return ListTile(
      title: Text(title,
          style: const TextStyle(
            fontWeight: FontWeight.w500,
            fontSize: 20,
          )),
      subtitle: Text(subtitle),
      leading: Icon(
        icon,
        color: Colors.blue[500],
      ),
    );
  }
}

 

 

Stack

:위젯을 다른 위젯 위에 겹칩니다.

stack_widget.dart

import 'package:flutter/material.dart';

class StackWidget extends StatelessWidget {
  const StackWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Stack',
      home: Scaffold(
          appBar: AppBar(
            title: const Text('It is a Stack demo'),
          ),
          body:_buildStack()
      ),
    );
  }

  Widget _buildStack() {
    return Stack(
      alignment: const Alignment(0.6, 0.6),
      children: [
        const CircleAvatar(
          backgroundImage: AssetImage('assets/images/dog1.jpg'),
          radius: 100,
        ),
        Container(
          decoration: const BoxDecoration(
            color: Colors.black45,
          ),
          child: const Text(
            'Dog ',
            style: TextStyle(
              fontSize: 40,
              fontWeight: FontWeight.bold,
              color: Colors.grey,
            ),
          ),
        ),
      ],
    );
  }
}

Dog 이라는 글자에 grey color 를 주고 black45 로 boxDecoration 하여 dog1.jpg 위에 올려 놓았다.

이와 같이 stack 에서는 각 위젯이  층층이 겹치게 표현 할 수 있다. 

Card

:모서리가 둥근 상자와 그림자가 있는 상자에 관련 정보를 구성합니다.

card_widget.dart

import 'package:flutter/material.dart';

class CardWidget extends StatelessWidget {
  const CardWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Card',
      home: Scaffold(
          appBar: AppBar(
            title: const Text('It is a Card demo'),
          ),
          body:_buildCard()
      ),
    );
  }
  Widget _buildCard() {
    return SizedBox(
      height: 210,
      child: Card(
        child: Column(
          children: [
            ListTile(
              title: const Text(
                '도산대로99길 ',
                style: TextStyle(fontWeight: FontWeight.w500),
              ),
              subtitle: const Text('서울시 , 강남구'),
              leading: Icon(
                Icons.restaurant_menu,
                color: Colors.blue[500],
              ),
            ),
            const Divider(),
            ListTile(
              title: const Text(
                '(02) 2233-1212',
                style: TextStyle(fontWeight: FontWeight.w500),
              ),
              leading: Icon(
                Icons.contact_phone,
                color: Colors.blue[500],
              ),
            ),
            ListTile(
              title: const Text('coffee@tea.com'),
              leading: Icon(
                Icons.contact_mail,
                color: Colors.blue[500],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Card 안에 Column 이 있고  children 에 ListTile 이 3개 있다.

첫번째 ListTile 은 title, subtitle, leading: icon 으로 구성되어 있고

그 이후 Divider 로 선을 하나 긋고

두번째 ListTile 은 title, leading: icon 으로 구성되어 있다. 

세번째 ListTile 도 title, leading: icon 으로 구성되어 있다. 

 

즉 아이콘과 text 로 ListTile 을 만들고 Card 형태로 외부를 감쌀 수 있다. 

 

빨간 표시를 한곳을 보면 카드 형태로 되어 있다. 

 

ListTile

:최대 3줄의 텍스트와 선택적인 선행 및 후행 아이콘을 행으로 구성합니다.

위 Card 에서 사용했다.

 

 

 

관련영상

https://youtu.be/sUI-WGz8FW0

 

반응형

'Flutter' 카테고리의 다른 글

기본 Layout 예제 만들기 (2)  (0) 2022.06.07
기본 Layout 예제 만들기 (1)  (0) 2022.06.06
Layout 1  (0) 2022.06.02
기본 위젯 (Widget) 2/2  (0) 2022.06.01
기본 위젯 (Widget)  (0) 2022.05.31