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

1. 소개

Material Design 및 Material Flutter 라이브러리란 무엇인가요?

머티리얼 디자인은 대담하고 멋진 디지털 제품을 빌드하는 시스템입니다. 일련의 일관된 원칙과 구성요소 아래 스타일과 브랜딩, 상호작용, 모션을 통합하여 제품팀은 가능한 최고의 디자인을 실현할 수 있습니다.

Material Flutter 라이브러리에는 앱과 플랫폼 전반에 걸쳐 일관적인 사용자 환경을 만들기 위해 Material Design 구성요소 (줄여서 MDC)의 디자인을 구현하는 Flutter 위젯이 포함되어 있습니다. 머티리얼 디자인 시스템이 발전함에 따라 이러한 구성요소는 Google의 프런트엔드 개발 표준을 준수하면서 일관된 픽셀 완벽 구현을 보장하도록 업데이트됩니다.

이 Codelab에서는 Material Flutter의 여러 구성요소를 사용하여 로그인 페이지를 빌드합니다.

빌드할 항목

이 Codelab은 Shrine 앱(의류와 가정용품을 판매하는 전자상거래 앱)을 빌드하는 방법을 설명하는 Codelab 네 개 중 첫 번째 Codelab입니다. Material Flutter를 사용하여 모든 브랜드 또는 스타일을 반영하도록 구성요소를 맞춤설정하는 방법을 보여줍니다.

이 Codelab에서는 다음이 포함된 Shrine의 로그인 페이지를 빌드합니다.

  • Shrine의 로고 이미지
  • 앱 이름(Shrine)
  • 텍스트 입력란 두 개. 하나는 사용자 이름 입력용, 하나는 비밀번호 입력용
  • 버튼 2개

Android

iOS

Android의 Shrine 로그인 페이지

iOS의 Shrine 로그인 페이지

이 Codelab의 Material Flutter 구성요소 및 하위 시스템

  • 텍스트 입력란
  • 버튼
  • 잉크 물결 효과 (터치 이벤트의 시각적 피드백 형식)

Flutter 개발 경험 수준을 평가해주세요.

초급 중급 고급

2. Flutter 개발 환경 설정

이 실습을 완료하려면 Flutter SDK편집기라는 두 가지 소프트웨어가 필요합니다.

다음 기기 중 하나를 사용하여 이 Codelab을 실행할 수 있습니다.

  • 컴퓨터에 연결되어 있으며 개발자 모드로 설정된 실제 Android 또는 iOS 기기
  • iOS 시뮬레이터(Xcode 도구 설치 필요)
  • Android Emulator(Android 스튜디오 설정 필요)
  • 브라우저(디버깅 시 Chrome 필요)
  • Windows, Linux 또는 macOS 데스크톱 애플리케이션. 배포에 사용할 플랫폼에서 개발해야 합니다. 따라서 Windows 데스크톱 앱을 개발하려면 적절한 빌드 체인에 액세스할 수 있도록 Windows에서 개발해야 합니다. docs.flutter.dev/desktop에 운영체제별 요구사항이 자세히 설명되어 있습니다.

3. Codelab 시작 앱 다운로드

시작 프로젝트는 material-components-flutter-codelabs-101-starter/mdc_100_series 디렉터리에 있습니다.

...또는 GitHub에서 클론

이 Codelab을 GitHub에서 클론하려면 다음 명령어를 실행하세요.

git clone https://github.com/material-components/material-components-flutter-codelabs.git
cd material-components-flutter-codelabs/mdc_100_series
git checkout 101-starter

프로젝트 열기 및 앱 실행

  1. 원하는 편집기에서 프로젝트를 엽니다.
  2. 선택한 편집기에 맞게 시작하기: 시험 운용의 '앱 실행'에 대한 안내를 따릅니다.

완료되었습니다. 기기에서 Shrine 로그인 페이지의 시작 코드가 실행되고 있어야 합니다. Shrine 로고와 그 바로 아래에 'Shrine' 이름이 표시됩니다.

Android

iOS

Shrine 로고

Shrine 로고

코드를 살펴보겠습니다

login.dart위젯

login.dart를 엽니다. 다음이 포함되어 있어야 합니다.

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)
          ],
        ),
      ),
    );
  }
}

import 문과 새 클래스 두 개가 포함되어 있습니다.

  • import 문을 사용하면 이 파일에서 Material 라이브러리를 사용할 수 있습니다.
  • LoginPage 클래스는 시뮬레이터에 표시되는 전체 페이지를 나타냅니다.
  • _LoginPageState 클래스의 build() 함수는 UI의 모든 위젯이 만들어지는 방식을 제어합니다.

4. TextField 위젯 추가

우선 사용자가 사용자 이름과 비밀번호를 입력하는 텍스트 입력란 두 개를 로그인 페이지에 추가합니다. 플로팅 라벨을 표시하고 터치 물결 효과를 활성화하는 TextField 위젯을 사용합니다.

이 페이지는 하위 요소를 스크롤 가능한 열에 정렬하는 ListView로 주로 구성됩니다. 아래에 텍스트 필드를 입력해 보겠습니다.

TextField 위젯 추가

const SizedBox(height: 120.0) 뒤에 새 텍스트 입력란 두 개와 공백을 추가합니다.

// TODO: Add TextField widgets (101)
// [Name]
TextField(
  decoration: const InputDecoration(
    filled: true,
    labelText: 'Username',
  ),
),
// spacer
const SizedBox(height: 12.0),
// [Password]
TextField(
  decoration: const InputDecoration(
    filled: true,
    labelText: 'Password',
  ),
  obscureText: true,
),

각 텍스트 입력란에는 InputDecoration 위젯을 사용하는 decoration: 입력란이 있습니다. filled: 입력란은 사용자가 텍스트 입력란의 탭이나 터치 영역을 쉽게 알아볼 수 있도록 텍스트 입력란의 배경이 가볍게 채워져 있음을 의미합니다. 두 번째 텍스트 입력란의 obscureText: true 값은 사용자가 입력하는 입력값을 비밀번호에 적합한 글머리 기호로 자동으로 바꿉니다.

핫 리로드를 실행하는 프로젝트를 저장합니다 (키 입력: command + s 사용).

이제 사용자 이름과 비밀번호에 사용할 텍스트 입력란 두 개가 포함된 페이지가 표시됩니다. 플로팅 라벨 애니메이션을 확인해보세요.

Android

iOS

사용자 이름 및 비밀번호 필드가 있는 Shrine 로고

사용자 이름 및 비밀번호 필드가 있는 Shrine 로고

5. 버튼 추가

이제 '취소'와 '다음' 버튼 두 개를 로그인 페이지에 추가합니다. 버튼 위젯으로는 TextButtonElevatedButton을 사용합니다.

OverBar 추가

텍스트 입력란 뒤 ListView의 하위 요소에 OverflowBar를 추가합니다.

// TODO: Add button bar (101)
OverflowBar(
  alignment: MainAxisAlignment.end,
  // TODO: Add a beveled rectangular border to CANCEL (103)
  children: <Widget>[
    // TODO: Add buttons (101)
  ],
),

OverflowBar는 그 하위 요소를 한 행으로 정렬합니다.

버튼 추가

그런 다음 OverflowBarchildren 목록에 버튼 두 개를 추가합니다.

    // TODO: Add buttons (101)
    TextButton(
      child: const Text('CANCEL'),
      onPressed: () {
        // TODO: Clear the text fields (101)
      },
    ),
    // TODO: Add an elevation to NEXT (103)
    // TODO: Add a beveled rectangular border to NEXT (103)
    ElevatedButton(
      child: const Text('NEXT'),
      onPressed: () {
    // TODO: Show the next page (101)
      },
    ),

프로젝트를 저장합니다. 마지막 텍스트 입력란 아래에 버튼 두 개가 표시됩니다.

Android

iOS

사용자 이름 및 비밀번호 필드, 취소 및 다음 버튼이 있는 Shrine 로고

사용자 이름 및 비밀번호 필드, 취소 및 다음 버튼이 있는 Shrine 로고

OverflowBar가 레이아웃 작업을 처리합니다. 버튼은 가로로 배치되므로 나란히 표시됩니다.

버튼을 터치하면 다른 작업이 실행되지 않고 잉크 물결 효과 애니메이션이 시작됩니다. 취소 버튼으로 텍스트 입력란을 지우고 다음 버튼으로 화면을 닫도록 익명 onPressed: 함수에 기능을 추가해보겠습니다.

TextEditingControllers 추가

텍스트 입력란의 값을 지울 수 있도록 TextEditingControllers를 추가하여 텍스트를 제어합니다.

_LoginPageState 클래스의 선언 바로 아래에 컨트롤러를 final 변수로 추가합니다.

  // TODO: Add text editing controllers (101)
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

첫 번째 텍스트 입력란의 controller: 입력란에서 _usernameController를 설정합니다.

// TODO: Add TextField widgets (101)
// [Name]
TextField(
  controller: _usernameController,

두 번째 텍스트 입력란의 controller: 입력란에서 이제 _passwordController를 설정합니다.

// TODO: Add TextField widgets (101)
// [Password]
TextField(
  controller: _passwordController,

onPressed 수정

TextButton의 onPressed: 함수에서 각 컨트롤러를 지우는 명령어를 추가합니다.

    // TODO: Clear the text fields (101)
    _usernameController.clear();
    _passwordController.clear();

프로젝트를 저장합니다. 이제 텍스트 입력란에 무언가를 입력할 때 취소를 누르면 각 입력란이 다시 지워집니다.

이 로그인 양식은 잘 작동합니다. 사용자를 Shrine 앱의 나머지 부분으로 안내해보겠습니다.

이 뷰를 닫으려면 탐색 스택에서 이 페이지(Flutter에서는 경로라고 함)를 (또는 삭제)합니다.

ElevatedButton의 onPressed: 함수에서 Navigator의 최신 경로를 표시합니다.

        // TODO: Show the next page (101)
        Navigator.pop(context);

마지막으로 home.dart를 열고 Scaffold에서 resizeToAvoidBottomInsetfalse로 설정합니다.

    return Scaffold(
      // TODO: Add app bar (102)
      // TODO: Add a grid view (102)
      body: Center(
        child: Text('You did it!'),
      ),
      // TODO: Set resizeToAvoidBottomInset (101)
      resizeToAvoidBottomInset: false,
    );

이렇게 하면 키보드의 모양으로 홈페이지나 홈페이지 위젯의 크기가 변경되지 않습니다.

이제 완료됐습니다. 프로젝트를 저장합니다. '다음'을 클릭해보세요.

축하합니다.

Android

iOS

'해냈어'라고 표시된 화면

'해냈어'라고 표시된 화면

이 화면은 MDC-102에서 작업할 다음 Codelab의 시작점입니다.

6. 축하합니다.

텍스트 입력란과 버튼은 추가했지만 레이아웃 코드는 거의 고려하지 않았습니다. Flutter용 머티리얼 구성요소는 다양한 스타일로 제공되며 화면에 손쉽게 배치할 수 있습니다.

다음 단계

텍스트 입력란과 버튼은 머티리얼 시스템의 두 가지 핵심 구성요소이지만 이 외에도 더 많은 요소가 있습니다. Material 구성요소 위젯 카탈로그에서 나머지도 살펴볼 수 있습니다.

또는 MDC-102: Material Design 구조 및 레이아웃으로 이동하여 Flutter용 MDC-102에서 다루는 구성요소에 관해 알아보세요.

적절한 시간과 노력을 들여 이 Codelab을 완료할 수 있었습니다.

매우 동의함 동의함 보통 동의하지 않음 전혀 동의하지 않음

앞으로 머티리얼 구성요소를 계속 사용하고 싶습니다.

매우 동의함 동의함 보통 동의하지 않음 전혀 동의하지 않음