본문 바로가기

개발/Study

[GoToLearn] Flutter CodeLab - MDC-101 Flutter:Material Components Basics

GoToLearn 2주차

GoToLearn 2주차 CodeLab과제인 MDC-101 Flutter:Material Components Basics을 진행해보겠습니다 !


MDC-101 Flutter:Material Components Basics

https://codelabs.developers.google.com/codelabs/mdc-101-flutter?hl=en#0

 

MDC-101 Flutter: 머티리얼 구성요소 기본사항  |  Google Codelabs

간단한 Flutter 앱의 로그인 페이지를 만들어 Material 구성요소 사용에 관한 기본사항을 알아봅니다.

codelabs.developers.google.com

 

1. 소개

Material Design 이란 ?

머터리얼 디자인이란 대담하고 멋진 디지털 제품을 빌드하는 시스템입니다. 머터리얼 디자인은 일관된 디자인 가이드라인을 제공해 모바일, 데스크톱 등 사용자에게 일관된 경험을 선사할 수 있습니다.

Material Flutter 라이브러리란 ?

Material Flutter 라이브러리는 앱과 플랫폼 전반에 걸쳐 일관적인 사용자 경험을 만들기 위해 Material Design 구성요소의 디자인을 구현하는 Flutter Widget을 포함하고 있습니다. Material Flutter 라이브러리는 머터리얼 디자인 시스템이 발전함에 따라 Google의 프론트앤드 개발 표준을 준수하면서 일관된 픽셀 완벽 구현을 보장하도록 합니다.

이번 코드랩에서 빌드할 항목

전자상거래 앱(Shrine)을 빌드하는 코드랩 중 첫 번째 코드랩이라고 합니다. Material Flutter Widget을 사용해서 모든 브랜드 또는 스타일을 반영하도록 컴포넌트를 커스터마이징하는 방법을 진행하고 Shirne 앱의 Login 페이지(로고, 앱 이름, 텍스트 입력, 버튼 2개)를 구현해봅니다.

사용하는 머터리얼 컴포넌트 및 하위 위젯

  • TextField (텍스트 필트)
  • Button (버튼)
  • Ink ripple (잉크 물결 효과)

2. 개발 환경 설정

개발을 하기 위해서는 Flutter SDK와 IDE(VS Code, Android Studio 등)이 설치가 필요합니다. 이미 환경 세팅은 완료되었기에 패스하도록 하겠습니다.


3. Codelab 시작 앱 다운로드

코드랩을 진행하기 위해 스타터 파일을 다운로드하거나 GitHub를 통해서 다운로드 받으면 됩니다. 저는 GitHub를 통해 진행하도록 하겠습니다.

git clone https://github.com/material-components/material-components-flutter-codelabs.git

 

스타터 앱을 다운로드 받고 pub get을 통해 필요한 라이브러리를 받은 뒤 실행하면 아래 화면을 확인할 수 있습니다.

스타터 로그인 화면

login.dart 내의 위젯

login.dart를 확인해보면 material 위젯을 사용하기 위한 import와 로그인 화면인 LoginPage가 있는것을 확인할 수 있습니다.

import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  // TODO: Add text editing controllers (101)
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.symmetric(horizontal: 24.0),
          children: <Widget>[
            const SizedBox(height: 80.0),
            Column(
              children: <Widget>[
                Image.asset('assets/diamond.png'),
                const SizedBox(height: 16.0),
                const Text('SHRINE'),
              ],
            ),
            const SizedBox(height: 120.0),
            // TODO: Remove filled: true values (103)
            // TODO: Add TextField widgets (101)
            // TODO: Add button bar (101)
          ],
        ),
      ),
    );
  }
}

4. TextField 위젯 추가

TextField 추가

사용자가 이름과 비밀번호를 입력 할 수 있는 텍스트필드를 2개 만들어 줍니다. 위젯 및 옵션에 대한 설명은 주석으로 표시하겠습니다.

class _LoginPageState extends State<LoginPage> {
  // TODO: Add text editing controllers (101)
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.symmetric(horizontal: 24.0),
          children: <Widget>[
            const SizedBox(height: 80.0),
            Column(
              children: <Widget>[
                Image.asset('assets/diamond.png'),
                const SizedBox(height: 16.0),
                const Text('SHRINE'),
              ],
            ),
            const SizedBox(height: 120.0),
            // TODO: Remove filled: true values (103)
            // TODO: Add TextField widgets (101)
            /// UserName TextField
            TextField(
              decoration: const InputDecoration(
                filled: true,
                labelText: 'UserName',
              ),
            ),
            const SizedBox(height: 12,),
            /// PassWord TextField
            TextField(
              decoration: const InputDecoration(
                filled: true,
                labelText: 'Password',
              ),
              /// 입력시 마스킹 표시
              obscureText: true,
            ),
            // TODO: Add button bar (101)
          ],
        ),
      ),
    );
  }
}

 

위 처럼 텍스트 필드를 구성하게 되면 다음과 같은 화면이 완성됩니다.

이름, 패스워드 텍스트 필드 추가


5. 버튼 추가

이제 로그인 할 때 취소 및 다음 버튼을 추가해야 합니다. 위젯은 TextButton과 ElevatedButton을 사용합니다.

Tip !
TextButton vs ElevatedButton
레이아웃에는 눈에 띄는 버튼 하나가 포함되어야 다른 버튼의 중요도가 낮다는 것이 명확하게 표현해줄 수 있습니다.
눈에 띄는 버튼은 사용자가 앱을 통해 진행하기 바라는 작업을 나타내는게 좋습니다.
사용자가 바라지 않는 작업은 눈에띄게 하지 않는 것이 좋습니다.
따라서 취소 / 다음 버튼에서 사용자에게 원하는 작업은 다음 버튼이고 원하지 않은 작업은 로그인 버튼이기 때문에 취소 버튼에 TextButton을 다음 버튼에 ElvatedButton을 적용하는게 좋습니다.

OverflowBar 추가

텍스트 필드 밑에 OverflowBar를 추가합니다. OverflowBar는 자식들을 정렬시킵니다.

/// OverflowBar와 alignment를 통해 우측 정렬 시켜 버리기
OverflowBar(
  alignment: MainAxisAlignment.end,
  children: [],
),

CANCEL, NEXT Button 추가

TextButton과 ElevatedButton을 사용해서 CANCEL 버튼과 NEXT 버튼을 추가해줍니다. OverflowBox가 자식인 버튼들이기때문에 우측으로 정렬됩니다.

TextButton(
  onPressed: () {},
  child: const Text('CANCEL'),
),
ElevatedButton(
  onPressed: () {},
  child: const Text('NEXT'),
),

TextEditingController 추가

텍스트 입력을 제어할 수 있는 TexteditingController를 유저명과 비밀번호 2개를 만들어준 뒤 TextField와 연결해줍니다.

  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
// [Name]
TextField(
  controller: _usernameController,
  
// [Password]
TextField(
  controller: _passwordController,

TextButton.onPressed 수정

취소 버튼을 선택했을 때 유저명과 패스워드를 클리어 시키도록 변경합니다.

TextButton(
  onPressed: () {
  _usernameController.clear();
  _passwordController.clear();
  },
  child: const Text('CANCEL'),
),

POP 처리

확인 버튼을 선택했을때 해당 화면이 pop(종료) 되도록 변경합니다.
또한 home.dart의 Scaffold의 resizeToAvoidBottomInset 속성을 false로 변경합니다.

resizeToAvoidBottomInset을 false로 설정하면 키보드로 인해 홈 페이지의 위젯 크기가 변경됨을 막을 수 있습니다.

ElevatedButton(
  onPressed: () {
  Navigator.pop(context);
  },
  child: const Text('NEXT'),
),
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('You did it!'),
      ),
      // resizeToAvoidBottomInset false 처리
      resizeToAvoidBottomInset: false,
    );
  }
}

6. 완성

위 코드랩까지 마치면 아래와 같은 결과물을 얻을 수 있습니다.

사용자에게 유저명과 비밀번호를 입력을 수 있고 취소 버튼을 통해 유저명과 비밀번호를 클리어, 다음 버튼을 통해 홈 페이지로 나갈 수 있는 앱을 완성하였습니다 !

MDC-101 완성


후기

개발하다 보면 사용할 수 밖에 없는 Button과 사용자 입력을 받는 TextField 및 Controller를 다시 확인할 수 있는 시간이었던것같습니다. 간단한 내용이라 별 어려움없이 진행할 수 있었던것 같네요 !

실습 코드

https://github.com/wonyong-park/flutter_codelabs/tree/main/material-components-flutter-codelabs-101-starter

 

flutter_codelabs/material-components-flutter-codelabs-101-starter at main · wonyong-park/flutter_codelabs

flutter_codelabs_repo. Contribute to wonyong-park/flutter_codelabs development by creating an account on GitHub.

github.com