카테고리 없음

코드팩토리의 플러터 프로그래밍 (책_플러터 위젯 템플릿)

stella0905 2024. 4. 9. 17:17

위젯 실습용 템플릿 작성

[ 기본코드 ]

import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
            child: // 1 여기에 예제 코드 작성하기
        ),
      ),
    );
  }
}

 

텍스트 관련 위젯

화면에 글자를 보여주려면 글자를 렌더링할 수 잇는 위젯을 사용해야 한다. 

[ Text 위젯 ] 

Text 위젯은 글자를 적고 스타일링 하는 위젯이다. 첫번째 포지셔널 파라미터에 원하는 문자열을 작성하고 style이라는 네임드 파라미터를 사용해 스타일을 지정한다.

          child: Text(
            // 작성하고 싶은 글
            '코드팩토리',
            // 글자에 스타일 적용
            style: TextStyle(
              // 글자 크기
              fontSize: 16.0,
              // 글자 굵기
              fontWeight: FontWeight.w700,
              // 글자 색상
              color: Colors.blue,
            ),
          ),

제스처 관련 위젯 

사용자가 키보드로 글자를 입력하는 행위 외의 모든 입력을 플러터에서는 제스처라고 부른다. 

예를 들어 화면을 한 번 탭한다거나, 두 번 탭한다거나 길게 누르는 행동 모두가 제스처이다. 

제스처 관련 위젯은 하위 위젯에 탭이나 드래그처럼 특정 제스처가 입력됐을 때 인지하고 콜백 함수를 실행한다. 

 

[ Button 위젯 ]

플러터 머터리얼 패키지에서 기본 제공하는 버튼으로 TextButton, OutlinedButton, ElevatedButton이 있다. 버튼을 누르면 색깔이 변경되는 리플 효과를 지원한다.

  • TextButton
TextButton(
    // 클릭 시 실행
    onPressed: () {},
    // 스타일 지정
    style: TextButton.styleFrom(
      // 주 색상 지정
      foregroundColor: Colors.red,
    ),
    // 버튼에 넣을 위젯
    child: Text('텍스트 버튼'),
  ),
  • OutlinedButton
OutlinedButton(
 // 클릭 시 실행할 함수
 onPressed: () {},
 // 버튼 스타일
 style: OutlinedButton.styleFrom(
  foregroundColor: Colors.red,
  ),
 // 버튼에 들어갈 위젯
 child: Text('아웃라인드 버튼'),
)
  • ElevatedButton
ElevatedButton(
 // 클릭 시 실행할 함수
 onPressed: (){},
 // 버튼 스타일링
 style: ElevatedButton.styleFrom(
  backgroundColor: Colors.red,
  ),
 // 버튼에 들어갈 위젯
 child: Text('엘레베이티드 버튼'),
),

 

[ IconButton 위젯 ]

아이콘을 버튼으로 생성하는 위젯이다. icon 매개변수에 보여주고 싶은 아이콘을 넣을 수 있다. 

onPressed 매개변수에 IconButton을 누르면 실행할 콜백 함수를 제공할 수 있다.

아이콘은 글리프 기반의 아이콘을 사용할 수 있으며 Icon클래스를 통해 제공하는 기본 아이콘들을 사용할 수 있다.

글리프란?
탭바, 버튼, 네비게이션바 등의 인터페이스 요소에 들어갈 공통적인 것들을 표현하기 위한 것
알아보기 쉽게, 매우 간단하게
앱의 모든 glyph는 시각적으로 일관성 되게 유지
IconButton(
 onPressed: () {},
 icon: Icon(
  // 1 플러터에서 기본으로 제공하는 아이콘입니다.
  // 제공되는 아이콘 목록은 다음 링크에서 확인해볼 수 있습니다.
  // https://fonts.google.com/icons
  Icons.home,
 ),
)

 

[ GestureDetector 위젯 ]

앱은 모든 입력을 손가락으로 한다. 그래서 손가락으로 하는 여러 가지 입력을 인지하는 위젯이 필요한데 그걸 gestureDetector가 그 역할을 한다.

GestureDetector(
// 1 한 번 탭했을 때 실행할 함수
    onTap: () {
// 출력 결과는 안드로이드 스튜디오의 [Run] 탭에서 확인 가능합니다.
      print('on tap');
    },
// 2 두 번 탭했을 때 실행할 함수
    onDoubleTap: () {
      print('on double tap');
    },
// 3 길게 눌렀을 때 실행할 함수
    onLongPress: () {
      print('on long press');
    },
// 제스처를 적용할 위젯
    child: Container(
      decoration: BoxDecoration(
        color: Colors.red,
      ),
      width: 100.0,
      height: 100.0,
    ),					
  ),

 

위젯에 한번 탭 두 번 탭, 길게 눌렀을때의 예제코드가 있다. 이뿐만이 아니라 웹에서의 오른쪽 클릭, 위젯 드래그 등의 입력도 받을 수 있다.

매개변수 설명
onTap 한 번 탭했을 때 실행되는 함수를 입력할 수 있습니다.
onDoubleTap 두 번 연속으로 탭했을 때 실행되는 함수를 입력할 수 있습니다.
onLongPress 길게 누르기가 인식됐을 때 실행되는 함수를 입력할 수 있습니다.
onPanStart 수평 또는 수직으로 드래그가 시작됐을 때 실행되는 함수를 입력할 수 있습니다.
onPanUpdate 수평 또는 수직으로 드래그를 하는 동안 드래그 위치가 업데이트될 때마다 실행되는 함
수를 입력할 수 있습니다.
onPanEnd 수평 또는 수직으로 드래그가 끝났을 때 실행되는 함수를 입력할 수 있습니다.
onHorizontalDragStart 수평으로 드래그를 시작했을 때 실행되는 함수를 입력할 수 있습니다.
onHorizontalDragUpdate 수평으로 드래그를 하는 동안 드래그 위치가 업데이트될 때마다 실행되는 함수를 입력할
수 있습니다.
onHorizontalDragEnd 수평으로 드래그가 끝났을 때 실행되는 함수를 입력할 수 있습니다.
onVerticalDragStart 수직으로 드래그를 시작했을 때 실행되는 함수를 입력할 수 있습니다.
onVerticalDragUpdate 수직으로 드래그를 하는 동안 드래그 위치가 업데이트될 때마다 실행되는 함수를 입력할
수 있습니다.
onVerticalDragEnd 수직으로 드래그가 끝났을 때 실행되는 함수를 입력할 수 있습니다.
onScaleStart 확대가 시작됐을 때 실행되는 함수를 입력할 수 있습니다.
onScaleUpdate 확대가 진행되는 동안 확대가 업데이트될 때마다 실행되는 함수를 입력할 수 있습니다.
onScaleEnd 확대가 끝났을 때 실행되는 함수를 입력할 수 있습니다.

 

[ FloatingAction Button 위젯 ]

Material Design에서 추구하는 버튼 형태이다. 앱들을 사용하다 보면 화면의 오른쪽 아래에 동그란 플로팅 작업 버튼을 쉽게 볼 수 있다. 

FloatingActionButtonScaffold를 같이 사용하면 특별한 어려움 없이 해당 형태의 디자인을 구현할 수 있다.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        floatingActionButton: FloatingActionButton(
// 클릭했을 때 실행할 함수
          onPressed: () {
            print('클릭');
          },
          child: Text('클릭'),
        ),
        body: Container(),
      ),
    );
  }
}

 

 

디자인 관련 위젯

디자인 관련 위젯은 배경을 추가하거나 간격을 추가하거나 패딩을 추가하는 등 디자인적 요소를 적용할 때 사용한다.

[ Container 위젯 ]

다른 위젯을 담는데 사용되고 너비와 높이를 지정하거나 배경이나 테두리를 추가할 때 많이 사용된다.

Container위젯은 다른 위젯들처럼 child 매개변수를 사용할 수 있다.

Container(
// 스타일 작용
      decoration: BoxDecoration(
// 배경 색깔 적용
        color: Colors.red,
// 테두리 적용
        border: Border.all(
// 테두리 굵기
          width: 16.0,
// 테두리 색상
          color: Colors.black,
        ),
// 모서리 둥글게 만들기
        borderRadius: BorderRadius.circular(
          16.0,
        ),
      ), // 높이
      height: 200.0,
// 너비
      width: 100.0,
    )

 

[ SizedBox 위젯 ]

위젯은 일반적으로 일정 크기의 공간을 공백으로 두고 싶을 때 사용된다. Container 위젯을 사용해도 공백을 만들 수 있지만

SizedBoxconst 생성자를 사용했을 때 퍼포먼스에서 이점을 얻을 수 있다.

SizedBox(
// 높이 지정
  height: 200.0,
// 너비 지정
  width: 200.0,
// SizedBox는 색상이 없으므로 크기를 확인하는
// 용도로 Container 추가
  child: Container(
    color: Colors.red,
  ),
) //

 

[ Padding 위젯 ]

 

child 위젯에 여백을 제공할 떄 사용한다. 상위 위젯과 하위 위젯 사이의 여백을 둘 수 있다. padding 매개변수는 EdgeInsets라는 값을 입력해야한다.  또한 child 매개변수에 Padding을 적용하고 싶은 위젯을 입력할 수 있다. 

 

Padding(
// 상하, 좌우로 모두 16픽셀만큼 패딩 적용
padding: EdgeInsets.all(
  16.0,
),
child: Container(
  color: Colors.red,
  width: 50.0,
  height: 50.0,
),
),

패딩은 적용된 위젯이 차지하는 크기 내부에서 간격이 추가된다. 마진은 따로 위젯이 존재하지 않고 Container위젯에 추가할 수 있다. 

EdgeInsets 클래스는 다양한 생성자를 제공한다.

생성자 설명
EdgeInsets.all(16.0) 상하, 좌우로 매개변수에 입력된 패딩을 균등하게 적용합니다.
EdgeInsets.symmetric(horizontal: 16.0,vertical: 16.0) 가로와 세로 패딩을 따로 적용합니다. Horizontal 매개변수에
가로로 적용할 패딩을 입력하고 Vertical 매개변수에 세로로 적
용할 패딩을 입력합니다.
EdgeInsets.only(top: 16.0, bottom: 16.0, left:16.0, right: 16.0) 위아래, 좌우 패딩을 따로 적용합니다. top, bottom, left,
right 매개변수에 각각 위아래 좌우 패딩을 입력할 수 있습니다.
EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 16.0)  위아래, 좌우 패딩을 따로 적용합니다. 포지셔널 파라미터를 좌,
위, 우, 아래 순서로 입력해주면 됩니다.

 

[ SafeArea ]

플러터는 가용되는 화면을 모두 사용하기 때문에 아이폰처럼 노치가 있는 핸드폰에서 노치에 위젯들이 가릴 수 있다. 

SafeArea위젯을 사용하면 따로 기기별로 예외처리를 하지 않고도 안전한 (Safe)화면에서만 위젯을 그릴 수 있다. 

 

배치 관련 위젯

하위 위젯을 가로 또는 세로로 배치하거나 위젯 위에 위젯을 겹칠 떄 사용한다.

 

[ Row 위젯 ]   

가로로 위젯을 배치하는데 사용되고 children매개변수를 노출한다. 

주축과 반대축이라는 개념이 존재하는데 row는 가로가 주축, 세로가 반대축이 되고, Column의 경우 반대가 된다. 

import 'package:flutter/material.dart';

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

class RowWidgetExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SizedBox(
// 반대축에서 이동할 공간을 제공하기 위해 높이를 최대한으로 설정
          height: double.infinity,
          child: Row(
// 주축 정렬 지정
            mainAxisAlignment: MainAxisAlignment.start,
            // 반대축 정렬 지정
            crossAxisAlignment: CrossAxisAlignment.center,
// 넣고 싶은 위젯 입력
            children: [
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.red,
              ),
// SizedBox는 일반적으로 공백을
// 생성할 때 사용
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.green,
              ),
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

[ Column 위젯 ]

Row위젯과 완전히 같은 매개변수들을 노출한다. 다만 주축과 반대축이 Row와 반대로 이루어져 있다. 

import 'package:flutter/material.dart';

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

class ColumnWidgetExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SizedBox(
// 반대축에서 이동할 공간을 제공해주기 위해 너비를 최대한으로 설정
          width: double.infinity,
          child: Column(
// 주축 정렬 지정
            mainAxisAlignment: MainAxisAlignment.start,
// 반대축 정렬 지정
            crossAxisAlignment: CrossAxisAlignment.center,
// 넣고 싶은 위젯 입력
            children: [
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.red,
              ),
// SizedBox는 일반적으로 공백을 생성할 때 사용
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.green,
              ),
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

[ Flexible 위젯 ]

Row나 Column에서 사용하는 위젯이다. Flexible에 제공된 child가 크기를 최소한으로 차지할 수 있다. 추가적으로 flex매개변수를 이용해 flexible위젯이 얼만큼의 비율로 공간을 차지할지 지정할 수 있다. 

Column(
    children: [
      Flexible(
    // flex는 남은 공간을 차지할 비율을 의미합니다.
    // flex값을 제공하지 않으면 기본값은 1입니다.
        flex: 1,
    // 파란색 Container
        child: Container(
          color: Colors.blue,
        ),
      ),
      Flexible(
        flex: 1,
    // 빨간색 Container
        child: Container(
          color: Colors.red,
        ),
      )
    ],
    ),

 

[ Expanded 위젯 ]

Flexible위젯을 상속하는 위젯이다. 

ColumnRow에서 Expanded사용하면 위젯이 남아 있는 공간을 최대한으로 차지한다. 

Flexible위젯은 fit 매개변수에 FlexFit.tight 또는 FlexFit.loose를 입력할 수 있다. FlexFit.loose는 자식 위젯이 필요한 만큼만 공간을 차지한다. 하지만 FlexFit.tight는  자식 위젯이 차지하는 공간과 관계없이 남은 공간을 모두 차지한다. Expanded위,젯은 Flexible위젯의 fit 매개변수에FlexFit.tight 를 기본으로 제공해주는 위젯으로 남는 공간을 최대한으로 차지하게 된다.

Column(
  children: [
// 파란색 Container
    Expanded(
      child: Container(
        color: Colors.blue,
      ),
    ),
// 빨간색 Container
    Expanded(
      child: Container(
        color: Colors.red,
      ),
    )
  ],
)),

 

[ Stack 위젯 ]

Stack위젯은 위젯을 겹치는 기능을 제공한다. 플러터는 그래픽엔진인 스키아 엔진은 2D 엔진이기 때문에 겹친 두께를 표한하지는 못하지만 Stack를 사용하면 위젯 위에 위젯을 올린 듯한 효과를 줄 수 있다. 

Stack(
    children: [
// 빨간색 Container
      Container(
        height: 300.0,
        width: 300.0,
        color: Colors.red,
      ),
// 노란색 Container
      Container(
        height: 250.0,
        width: 250.0,
        color: Colors.yellow,
      ),
// 파란색 Container
      Container(
        height: 200.0,
        width: 200.0,
        color: Colors.blue,
      ),
    ],
  ),

Stack는 children에 위치한 순서대로 위젯을 겹쳐싼다. 컨테이너가 점점 가로, 세로, 50 픽셀씩 작아지고 있어 먼저 그려진 컨테이너가 가로 세로 50픽셀만큼 더 크게 그려진다.