가끔 보자, 하늘.

Flutter 로 앱 개발 및 릴리즈 - 03. Flutter Compoent와 Native Component 본문

개발 이야기/개발 및 서비스

Flutter 로 앱 개발 및 릴리즈 - 03. Flutter Compoent와 Native Component

가온아 2025. 5. 9. 09:00

처음 flutter 프로젝트를 생성한 후 앞에서 보았던 OS별로 생성된 다수의 폴더를 보고 놀란 사람이 저만은 아니겠죠. 처음에는 저 수많은 폴더들과 환경설정들을 어떻게 해야 까마득 했는데 컴포넌트에 대해 살펴보다 다음과 같은 AI 답변을 보고 그나마 안심했습니다. (아직 방심하기는 금물일지도. Flutter를 보기 시작한지 이틀인 상태이니 이미 알고 계신 분들은 양해를 부탁드립니다. ^^;  댓글 훈수도 대환영합니다. )

Q) 요점은 각 OS별 전용 컴포넌트를 사용할 수 있지만 flutter component로 구성하면 각 OS 별 전용 컴포넌트로 자동 구성된다는 말인가?
A) 네. 말씀하신 내용이 핵심입니다. 다시 정리해 드리자면,
핵심 요약:
• Flutter Component (Flutter View): Flutter로 작성한 코드에서 사용하는 Widget들은 Flutter Component, 즉, Flutter View 입니다. 예를 들어, NavigationBar, BottomNavigationBar, Text, Column, Row, Image, Button 등이 모두 Flutter Component입니다.
• 플랫폼 전용 컴포넌트 (Native View): Android의 BottomNavigationView, iOS의 UITabBar, 웹의 <nav> 등과 같이, 각 OS(플랫폼)에서 제공하는 UI 컴포넌트를 Native View 또는 플랫폼 전용 컴포넌트라고 부를 수 있습니다.
• Flutter의 역할 (Flutter View to Native View): Flutter의 역할은 사용자가 Flutter Component로 UI를 구성하면, Flutter가 이를 각 OS에 맞는 Native View로 변환하여 렌더링한다는 점입니다. 즉, Flutter는 일종의 중개자 또는 번역가 역할을 합니다.
• Flutter View는 각 플랫폼에 최적화된 Native View로 변환됩니다. 좀 더 자세한 설명:
    1. Flutter Component를 사용한 개발: 개발자는 Flutter의 NavigationBar (또는 BottomNavigationBar)와 같은 Component를 사용하여 네비게이션 바를 구현합니다. 코드는 한 번만 작성합니다.
    2. 빌드 시점: 앱을 빌드할 때, Flutter는 작성된 Flutter Component 코드를 각 플랫폼에 맞게 해석합니다.
    3. 실행 시점:
        • Android: Flutter는 NavigationBar를 Android에서 가장 적합한 UI 컴포넌트(예: BottomNavigationView와 같은 Native View, 실제로 BottomNavigationView는 아니지만, 같은 역할을 하는 네이티브 뷰로 구현합니다.)로 변환하여 화면에 렌더링합니다. 안드로이드 네이티브 뷰로 그려집니다.
        • iOS: Flutter는 NavigationBar를 iOS에서 가장 적합한 UI 컴포넌트(예: UITabBar와 같은 Native View, 실제로 UITabBar는 아니지만, 같은 역할을 하는 네이티브 뷰로 구현합니다.)로 변환하여 화면에 렌더링합니다. iOS 네이티브 뷰로 그려집니다.
        • Web: Flutter는 NavigationBar를 웹에서 가장 적합한 UI 컴포넌트(예: <nav>, <div> 등의 HTML 요소와 CSS, 실제로 <nav>는 아니지만, 같은 역할을 하는 웹 뷰로 구현합니다.)로 변환하여 화면에 렌더링합니다. 웹뷰로 그려집니다.
        • macOS, Windows, Linux: 동일한 방식으로, 각 플랫폼의 디자인 가이드라인과 UI 구성 요소에 맞게 변환하여 렌더링합니다.
    4.개발자는 Native View를 직접 관리할 필요가 없습니다. 개발자는 Flutter Component만 사용하여 UI를 구성하면 됩니다. Flutter가 각 플랫폼에 맞게 변환해 주기 때문에, 개발자는 플랫폼별 코드를 직접 작성하거나 관리할 필요가 없습니다. 이것이 Flutter의 큰 장점입니다.
    5.다만, 직접 각 OS별 전용 컴포넌트를 사용할 수 있습니다.
        • Flutter는 MethodChannel, PlatformView등을 통해 각 OS별 네이티브 View를 사용할 수 있습니다.
        • 하지만, Flutter Component로 구성하면 이러한 Native View를 사용할 필요가 없어집니다.

정리:
    • Flutter Component를 사용하면, 각 OS별 Native View로 자동 구성됩니다.
    • 개발자는 플랫폼별 Native View를 직접 다룰 필요 없이, Flutter Component만 사용하면 됩니다.
    •다만, 개발자가 원하면 각 OS별 Native View를 직접 다룰 수 있습니다.

(* Gemini와의 대화는 포멧이 잘 맞지 않고 불필요한 미사여구가 많아 일부 수정했습니다)

이제 좀 마음이 편안해졌네요. 하지만 아직 안심은 근물!! 컴포넌트를 하나씩 붙여가며 이 의심을 없애 봐야겠네요.

드디어 첫 컴포넌트를 만들어 봐야겠네요. Navi bar를 추가해 보겠습니다. 

그 전에 main.dart의 내용은 다음과 같이 수정합니다. 다음에 추가할 NaviBar를 추가하고 샘플 컴포넌트는 모두 삭제합니다. (편의를 위해 주석은 삭제하고 올립니다.)

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

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true, // Material 3 사용 설정
      ),
      home: const NaviBar(), // NaviBar 컴포넌트를 홈 화면으로 설정
    );
  }
}

src/navi_bar.dart 파일을 만들고 아래 코드를 작성합니다. (이어지는 모든 코드는 Gemini를 통해 생성하고 필요한 경우 일부 수정합니다. 본문 길이를 위해 꼭  필요한 주석만 남깁니다. 설명이 필요한 부분은 댓글로 문의 주시거나 Gemini에게 설명을 요구해 보세요.)

import 'package:flutter/material.dart';

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

  @override
  State<NaviBar> createState() => _NaviBarState();
}

class _NaviBarState extends State<NaviBar> {
  int _selectedIndex = 0;

  // 각 탭에 보여줄 위젯을 담을 리스트
  // 추후 각 페이지 연동을 여기에. 지금은 중앙에 라벨 출력으로 마무리
  final List<Widget> _pages = <Widget>[
    const Center(child: Text('Calendar')),
    const Center(child: Text('Project')),
    const Center(child: Text('Setting')),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_selectedIndex], // 선택된 탭에 맞는 페이지를 보여줌
      bottomNavigationBar: NavigationBar(
        selectedIndex: _selectedIndex,
        onDestinationSelected: _onItemTapped,
        destinations: const <Widget>[
          NavigationDestination(
            icon: Icon(Icons.looks_one),
            label: 'Calendar',
          ),
          NavigationDestination(
            icon: Icon(Icons.looks_two),
            label: 'Project',
          ),
          NavigationDestination(
            icon: Icon(Icons.looks_3),
            label: 'Setting',
          ),
        ],
      ),
    );
  }
}

이제 실행하면 다음과 같은 결과를 확인 하실 수 있습니다. 

 

이런!! 이 프로젝트의 기획을 이야기하지를 않았군요. 간단히 정리하자면..

  • 목표 : 개발자를 위한 ToDo 앱을 개발하고 수익화를 위해 광고 혹은 대체 방법을 적용해 릴리즈
  • 앱의 주요 기능
    • 프로젝트 별로 할 일을 등록
    • 데드라인, 중요도를 설정
    • 일정 변경을 손쉽게. 
    • 데드라인 알람.
    • firebase 연동해서 사용자 정보 저장 및 검색
    • 무리한 일정에 대한 경고 및 추천안 (AI활용)
    • 수익화 방식 (adsense를 연동)
  • 앱 주요 UI
    • 캘린더로 일정 보기
    • 프로젝트 별로 일정 보기
    • 앱설정

위 목표를 달성하기 위한 첫 걸음으로 오늘은 Navi bar를 구현했으며 앞으로 각 페이지를 구현하며 다양한 컴포넌트를 활용해 보겠습니다. 

그리고 코드에 대해서는 꼭 필요한 부분만 설명하겠습니다. 왜냐면... 저도 이번이 처음이라.. ^^;;; 

AI를 많이 활용해 보시고 그래도 안되는 내용 있으면 댓글을 달아주세요. 따로 공부해서라도 답변 드리겠습니다. :)

모두 즐거운 주말 되세요. :)

 

반응형