Flutter - Cupertino - 개념, 샘플 코드, 사용 예시(Button, TextField, TabBar, NavigationBar, Switch, AlertDialog, ActivityIndicator)

반응형

포스팅에서 사용된 예시 프로젝트 파일은 깃허브에서 다운로드 가능합니다.

https://github.com/luvris2/flutter-example/tree/main/flutter_cupertino_test


Cupertino

정의

  • Apple의 iOS 운영 체제의 디자인 가이드라인을 따르는 Flutter의 위젯
  • iOs와 macOS에서 잘 작동하며 디자인 또한 iOS의 네이티브 앱과 유사
  • iOS 앱 개발자들이 익숙한 디자인 패턴과 위젯을 Flutter에서 사용할 수 있게 만들어줌
  • iOS에서 실행되는 앱을 위해 설계
    • 때문에 다른 운영 체제에서도 실행 될 수 있는 앱일 경우 다른 위젯 사용 고려
    • 플러터 공식 가이드에서는 'Material Design' 위젯과 함께 사용을 권장하고 있음
      • Material Design 위젯 : 구글의 안드로이드 디자인 가이드를 따르는 위젯

라이브러리 호출

  • 다트 코드 최상단에 아래의 코드 추가
import 'package:flutter/cupertino.dart';

Cupertino 위젯 샘플 코드 (사용 예시)

  • 쿠퍼티노 위젯의 종류가 많으므로 이 포스팅에서는 특정 몇 개의 위젯만 예시로 다룹니다.

 

CupertinoButton

  • 버튼을 눌러 특정 작업을 수행할 수 있는 위젯
  // 배경이 채워진 쿠퍼티노 버튼
  CupertinoButton.filled(
    child: const Text('Press me!'),
    onPressed: () {},
  ),
  // 배경이 채워지지 않은 쿠퍼티노 버튼
  CupertinoButton(
    child: const Text('Press me!'),
    onPressed: () {},
  ),
  // 배경이 채워진 쿠퍼티노 비활성 버튼
  const CupertinoButton.filled(
    onPressed: null,
    child: Text('Press me!'),
  ),
  // 배경이 채워지지 않은 쿠퍼티노 비활성 버튼
  const CupertinoButton(
    onPressed: null,
    child: Text('Press me!'),
  ),


CupertinoTextField

  • 사용자가 문자를 입력할 수 있는 위젯
  // 쿠퍼티노 텍스트 필드
  CupertinoTextField(
    placeholder: 'Enter text',
    onChanged: (text) {
      // 입력 값이 변경될 때 실행될 코드
    },
  ),


CupertinoTabBar (=BottomNavigationBar)

  • 앱 하단에 특정 페이지로 이동하기 위해 사용하는 위젯
  • MaterialApp의 BottomNavigationBar와 동일한 기능
// 쿠퍼티노 탭 바 (바텀 내비게이션 바)
CupertinoTabBar(
  items: const <BottomNavigationBarItem>[
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.star_fill),
      label: 'Favourites',
    ),
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.clock_solid),
      label: 'Recents',
    ),
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.person_alt_circle_fill),
      label: 'Contacts',
    ),
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.circle_grid_3x3_fill),
      label: 'Keypad',
    ),
  ],
),


CupertinoSwitch

  • 버튼을 눌러 '예/아니오'의 값이 토글되는 위젯
// 쿠퍼티노 스위치 토글을 위한 값
  bool switchValue = true;

  // 쿠퍼티노 스위치
  CupertinoSwitch(
    // 부울 값으로 스위치 토글 (value)
    value: switchValue,
    activeColor: CupertinoColors.activeBlue,
    onChanged: (bool? value) {
      // 스위치가 토글될 때 실행될 코드
      setState(() {
        switchValue = value ?? false;
      });
    },
  ),


CupertinoNavigationBar (=AppBar)

  • 앱의 상단에 제목과 특정 작업을 수행할 수 있는 버튼을 추가할 수 있는 위젯
  • MaterialApp의 AppBar와 동일한 기능
// 쿠퍼티노 내비게이션 바 (앱 바)
CupertinoNavigationBar(
  middle: const Text('Title'),
  trailing: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      CupertinoButton(
        padding: EdgeInsets.zero,
        child: const Icon(
          CupertinoIcons.question_circle_fill,
          size: 30,
        ),
        onPressed: () {
          // 액션 버튼이 눌렸을 때 실행될 코드
        },
      ),
    ],
  ),
),


CupertinoAlertDialog

// 쿠퍼티노 다이얼로그
CupertinoAlertDialog(
    title: const Text('알림'),
    content: const Text('쿠퍼티노 다이얼로그 내용'),
    actions: <CupertinoDialogAction>[
      CupertinoDialogAction(
        // isDefaultAction
        // 작업의 기본 값
        // 텍스트 색상을 파란색으로, 굵게 표시
        isDefaultAction: true,
        onPressed: () => Navigator.pop(context),
        child: const Text('No'),
      ),
      CupertinoDialogAction(
        // isDestructiveAction
        // 작업 수행, 삭제 및 전환과 같은 파괴적인 작업
        // 텍스트 색상을 빨간색으로 지정
        isDestructiveAction: true,
        onPressed: () => Navigator.pop(context),
        child: const Text('Yes'),
      ),
    ],
  ),


CupertinoActivityIndicator

  • 앱의 특정 작업을 수행할 때 사용자에게 수행 중인 상태를 표시하기 위해 사용하는 위젯
  • 프로그레스 바의 개념과 동일
  // 쿠퍼티노 액티비티 인디캐이터 (진행 표시 바, 프로그레스 바)
  CupertinoActivityIndicator(
      radius: 20.0, color: CupertinoColors.activeBlue),
  SizedBox(height: 10),
  Text(
    'radius: 20.0\ncolor: CupertinoColors.activeBlue',
    textAlign: TextAlign.center,
  ),


전체 코드

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Cupertino Demo',
      home: CupertinoExample(),
    );
  }
}

class CupertinoExample extends StatefulWidget {
  const CupertinoExample({super.key});

  @override
  State<CupertinoExample> createState() => _CupertinoState();
}

class _CupertinoState extends State<CupertinoExample> {
  // 쿠퍼티노 스위치 토글을 위한 값
  bool switchValue = true;

  // 쿠퍼티노 다이얼로그
  void _showAlertDialog(BuildContext context) {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => CupertinoAlertDialog(
        title: const Text('알림'),
        content: const Text('쿠퍼티노 다이얼로그 내용'),
        actions: <CupertinoDialogAction>[
          CupertinoDialogAction(
            // isDefaultAction
            // 작업의 기본 값
            // 텍스트 색상을 파란색으로, 굵게 표시
            isDefaultAction: true,
            onPressed: () => Navigator.pop(context),
            child: const Text('No'),
          ),
          CupertinoDialogAction(
            // isDestructiveAction
            // 작업 수행, 삭제 및 전환과 같은 파괴적인 작업
            // 텍스트 색상을 빨간색으로 지정
            isDestructiveAction: true,
            onPressed: () => Navigator.pop(context),
            child: const Text('Yes'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        // 쿠퍼티노 내비게이션 바 (앱 바)
        appBar: CupertinoNavigationBar(
          middle: const Text('Title'),
          trailing: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              CupertinoButton(
                padding: EdgeInsets.zero,
                child: const Icon(
                  CupertinoIcons.question_circle_fill,
                  size: 30,
                ),
                onPressed: () {
                  // 액션 버튼이 눌렸을 때 실행될 코드
                  // 쿠퍼티노 다이얼로그 호출
                  _showAlertDialog(context);
                },
              ),
            ],
          ),
        ),
        body: SingleChildScrollView(
          child: Center(
            child: Padding(
              padding: const EdgeInsets.all(15.0),
              child: Column(
                children: [
                  // 배경이 채워진 쿠퍼티노 버튼
                  CupertinoButton.filled(
                    child: const Text('Press me!'),
                    onPressed: () {},
                  ),
                  // 배경이 채워지지 않은 쿠퍼티노 버튼
                  CupertinoButton(
                    child: const Text('Press me!'),
                    onPressed: () {},
                  ),
                  // 배경이 채워진 쿠퍼티노 비활성 버튼
                  const CupertinoButton.filled(
                    onPressed: null,
                    child: Text('Press me!'),
                  ),
                  // 배경이 채워지지 않은 쿠퍼티노 비활성 버튼
                  const CupertinoButton(
                    onPressed: null,
                    child: Text('Press me!'),
                  ),
                  // 쿠퍼티노 텍스트 필드
                  CupertinoTextField(
                    placeholder: 'Enter text',
                    onChanged: (text) {
                      // 입력 값이 변경될 때 실행될 코드
                    },
                  ),
                  // 쿠퍼티노 스위치
                  CupertinoSwitch(
                    // 부울 값으로 스위치 토글 (value)
                    value: switchValue,
                    activeColor: CupertinoColors.activeBlue,
                    onChanged: (bool? value) {
                      // 스위치가 토글될 때 실행될 코드
                      setState(() {
                        switchValue = value ?? false;
                      });
                    },
                  ),
                  // 쿠퍼티노 액티비티 인디캐이터
                  const CupertinoActivityIndicator(
                      radius: 20.0, color: CupertinoColors.activeBlue),
                  const SizedBox(height: 10),
                  const Text(
                    'radius: 20.0\ncolor: CupertinoColors.activeBlue',
                    textAlign: TextAlign.center,
                  ),
                ],
              ),
            ),
          ),
        ),
        // 쿠퍼티노 탭 바(바텀 내비게이션 바)
        bottomNavigationBar: CupertinoTabBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.star_fill),
              label: 'Favourites',
            ),
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.clock_solid),
              label: 'Recents',
            ),
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.person_alt_circle_fill),
              label: 'Contacts',
            ),
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.circle_grid_3x3_fill),
              label: 'Keypad',
            ),
          ],
        ),
      ),
    );
  }
}

샘플 앱 실행


참고

반응형