Flutter

플러터 기본기 - 위젯 사용법

ryeonng 2024. 11. 6. 12:30

기초적인 Flutter 화면을 구성하는 패턴

  1. 'package:flutter/material.dart' 임포트
  2. MaterialApp으로 메인 위젯 트리 감싸기
  3. title과 theme과 같은 속성 설정
  4. home : 속성을 주 페이지로 정의
  5. Scaffold :
    • 앱의 시각적 레이아웃에 대한 기본 구조 제공
    • appBar 및 body와 같은 속성 설정
      • 레이아웃 요소 제공 (예 : AppBar, Drawer, BottomNavigationBar)
        • 각 구성요소는 또 다른 위젯으로 각각의 사용법은 이후에 정리하기로 함
      • body에 실제 화면 관련 위젯 정의
import 'package:flutter/material.dart';

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

// 상태 기반 UI
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    // 앞으로 MaterialApp 안에서 위젯들을 선언해보자.
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'My Flutter',
      theme: ThemeData(colorScheme: ColorScheme.light(primary: Colors.redAccent),
        primarySwatch: Colors.red
      ),
      // Scaffold : 시각적 레이아웃 구성요소를 잡아준다.
      home: Scaffold(
        appBar: AppBar(title: Text("My Flutter"), backgroundColor: Colors.blue,),
      ), // home : 실제로 화면에 보일 부분 (html의 body 영역)
    );
  }
}

 

MaterialApp의 주요 property와 사용법

  • theme : 앱의 전체 테마, 색상 구성 등이 포함 ( 예) theme : ThemeData(primarySwatch : Colors.red) )
  • home : 앱이 시작할 때 보여질 기본 경로 또는 위젯

scaffold 위젯 사용법과 주요 property

  • MaterialApp 내에서 material 디자인의 기본 레이아웃 구조를 제공하는 위젯
  • 주요 property
    • appBar : 화면의 상단에 위치한 앱 바
      • 보통 value로 AppBar(title : const Text('FunCoding'))과 같이 AppBar 위젯을 넣는 경우가 많다.
    • body : 화면의 기본 내용, 일반적으로는 위젯의 목록
    • floatingActionButton : 인터페이스에 위치한 추가 버튼
      • floatingActionButtonLocation : 부가 버튼의 위치
    • drawer : Scaffold 위젯의 사이드 메뉴
    • persistentFooterButtons : 화면 하단에 표시되는 버튼의 행
    • bottonNavigationBar : 화면 하단에 표시되는 네비게이션 바
    • backgroundColor : Scaffold의 배경색
    • resizeToAvoidBottomInset : 스크린 키보드를 피하기 위해 body의 크기를 자동으로 조정할지 여부 설정(default : true)
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.orange),
      debugShowCheckedModeBanner: false, // 디버그 띠 지우기
      home: Scaffold(
        appBar: AppBar(
          title: Text("Co Burn Studio"),
          backgroundColor: Colors.orange,
        ),
        body: Center(
          child: Padding(
            padding: EdgeInsets.all(120.0),
            child: TextField(
              decoration: InputDecoration(labelText: '입력요망'),
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          elevation: 5.0,
          child: Icon(Icons.add),
          // () {} : 익명 함수 (dart 언어에서는 익명 클래스 개념은 존재하지 않음)
          onPressed: () {
            print("111111111");
          }, // onPressed : 필수값, 이벤트리스너
        ),
        drawer: Drawer(
          child: ListView(
            children: [
              ListTile(
                title: Text("item 1"),
              ),
              ListTile(
                title: Text("item 2"),
              ),
            ],
          ),
        ),
        // persistentFooterButtons: [
        //   Icon(Icons.settings),
        //   SizedBox(
        //     width: 50,
        //   ), // 공백
        //   Icon(Icons.person),
        // ],
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: 1,
          fixedColor: Colors.blue,
          backgroundColor: Colors.amberAccent,
          items: [
            BottomNavigationBarItem(
              label: '검색',
              icon: Icon(Icons.search_rounded),
            ),
            BottomNavigationBarItem(
              label: '홈',
              icon: Icon(Icons.home),
            ),
        BottomNavigationBarItem(
          label: 'My',
          icon: Icon(Icons.person),
        ),
          ],
        ),
      ),
    );
  }
}

 

AppBar 사용법과 주요 property

  • backgroundColor : AppBar 배경색
  • elevation : AppBar를 어느정도 떠오르게 설정 (그림자의 깊이가 달라진다.)
  • title : 보통 Text 위젯으로 타이틀 표시
  • centerTitle : true로 설정 시, 타이틀이 가운데로 위치
  • leading : 제목 앞에 표시되는 위젯. 보통 IconButton 위젯으로 메뉴 등을 표시
  • actions : 제목 뒤에 표시되는 위젯. 보통 IconButton 위젯으로 메뉴 등을 표시
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text("tencoding"),
          actions: [
            IconButton(
              onPressed: () {},
              icon: Icon(Icons.add),
            ),
            IconButton(
              onPressed: () {},
              icon: Icon(Icons.search),
            ),
          ],
          leading: IconButton(
            onPressed: () {},
            icon: Icon(Icons.menu),
          ),
          elevation: 20.0,
        ),
      ),
    );
  }
}

 

Stack 위젯

  • Row 위젯은 내부 위젯을 수평으로 나열하는 위젯, Column 위젯은 내부 위젯을 수직으로 나열하는 위젯
  • Stack 위젯은 내부 위젯을 겹쳐서 나열하는 위젯
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Stack(
          children: [
            Container(
              width: 400,
              height: 400,
              decoration: BoxDecoration(
                color: Colors.pinkAccent
              ),
            ), // 컨테이너는 자식 크기만큼 줄어드는 성질을 가진다.
            Container(
              width: 300,
              height: 300,
              decoration: BoxDecoration(
                  color: Colors.blue
              ),
            ),
            Positioned(
              top: 50,
              left: 50,
              child: Container(
                width: 50,
                height: 50,
                decoration: BoxDecoration(
                    color: Colors.yellowAccent
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

 

Align 위젯

  • 자식 위젯을 특정 위치에 정렬하기 위해 사용하는 위젯
  • 특정 위치에 위젯을 배치하기 위한 위젯은 Align과 Positioned가 있지만
  • Positioned는 Stack 안에서만 사용 가능하고, Align은 독립적으로도 사용이 가능하다.
  • Align에서 자식 위젯의 위치는 alignment 속성으로 설정
    • alignment 속성값은 주로 Alignment 클래스 설정값 (예 : Alignment.bottomRight, 오른쪽 하단부에 위치)

Alignment 주요 값

  • Alignment.topLeft : 위젯을 부모 위젯의 왼쪽 상단 모서리에 맞춘다.
  • Alignment.topCenter : 위젯을 부모 위젯의 상단 중앙에 맞춘다.
  • Alignment.topRight : 위젯을 부모 위젯의 오른쪽 상단 모서리에 맞춘다.
  • Alignment.centerLeft : 위젯을 부모 위젯의 중앙 왼쪽에 맞춘다.
  • Alignment.center : 위젯을 부모 위젯의 중앙에 맞춘다.
  • Alignment.centerRight : 위젯을 부모 위젯의 중앙 오른쪽에 맞춘다.
  • Alignment.bottomLeft : 위젯을 부모 위젯의 왼쪽 하단 모서리에 맞춘다.
  • Alignment.bottomCenter : 위젯을 부모 위젯의 하단 중앙에 맞춘다.
  • Alignment.bottomRight : 위젯을 부모 위젯의 오른쪽 하단 모서리에 맞춘다.
  • Alignment(x, y) : 위젯을 (x, y)로 지정된 점에 맞춘다. (-1, -1)은 상단 좌측 모서리, (0, 0)은 중앙, (1, 1)은 하단 우측 모서리를 나타낸다.

 

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            "Align Widget Example",
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
        ),
        body: Center(
          child: Container(
            height: 200,
            width: 200,
            decoration: BoxDecoration(
                color: Colors.lightBlueAccent,
                borderRadius: BorderRadius.all(
                  Radius.circular(30.0),
                )),
            child: Align(
              //alignment: Alignment.bottomCenter,
              alignment: Alignment(0.5,0.5),
              child: Text("Hello World"),
            ),
          ),
        ),
      ),
    );
  }
}

 

Expanded 위젯

  • 위젯 크기를 수치로 설정하지 않고, 비율로 설정할 때 사용하는 위젯
  • 화면 사이즈가 다양할 수 있기 때문에, 수치로 위젯 크기를 설정할 경우, 여러 화면 사이즈 대응이 어려울 수 있다.
  • 따라서, 비율로 위젯 크기를 설정하는 방법에 대해 알아둘 필요가 있다.
  • Expanded 위젯의 flex 속성은 각 자식 위젯이 다른 자식 위젯과 비교하여 차지해야 하는 공간의 양을 지정하는 데 사용한다.
  • 다음 예제에서는 첫 번째 Expanded 위젯의 flex 속성을 1로, 두 번째 Expanded 위젯의 flex 속성을 2로 설정
    • 첫 번째 Expanded 위젯은 Column의 1/3, 두 번째 Expanded 위젯은 Column의 2/3 공간을 차지하며 화면에 표시된다.
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SizedBox(
          width: double.infinity,
          child: Column(
            children: [
              Expanded(
                flex: 2,
                child: Container(
                  color: Colors.redAccent,
                  child: Center(child: Text("first item")),
                ),
              ),
              Expanded(
                flex: 1,
                child: Container(
                  color: Colors.lightGreenAccent,
                  child: Center(child: Text("second item")),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

'Flutter' 카테고리의 다른 글

플러터 기본 - Form 위젯  (0) 2024.11.15
플러터 기본 2  (3) 2024.11.07
플러터 기본기 다지기  (2) 2024.11.05
dart(함수, 메서드)  (0) 2024.09.06
dart Null Safety  (1) 2024.09.06