23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
.png)
그럼, 차근차근 설명해보죠...
위에서 보시는것과 같이 기본적으로 android와 ios 가 눈에 띄실텐데요...맞습니다.
flutter 를 사용하면 코드하나로 android 와 ios 앱을 만들 수 있습니다.
그리고, 개발자의 시각으로 보시면... lib 가 눈에 들어오실거고 그다음 test 라는 디렉토리가 가장 먼저 눈에 들어오실거예요....
간단하게 표로 정리해보면 아래와 같습니다.
.png)
root 디렉토리를 보시면....아래와 같이 여러가지 파일이 존재함을 또한 확인하실 수 있습니다.
.png)
그럼, 차근차근 알아보죠...
참고로, 아래와 같이 총 7가지가 있는데요...
3개의 파일은 직접관리하고, 4개의 파일은 자동관리되는 성격을 띠게되어 있습니다.
.png)
총 7개의 파일 중에 우리가 관심있고 주목해야할 파일이 한개있는데요..
바로 "pubspec.yaml" 파일입니다.
왜냐하면, 해당 파일은 flutter관련 "package / image / font 설정하는 파일" 이고 해당 설정을 통해서 사용할 수 있게 해주기 때문입니다.
그리고, 실제적으로 보면 프로그래밍과 연관된 파일이기때문이죠
name: magic_flutter_app
description: A new Flutter Magic demo application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# magic_flutter_app
A new Flutter Magic demo application.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 1d9032c7e1d867f071f2277eb1673e8f9b0274e3
channel: stable
project_type: app
# This file is deprecated. Tools should instead consume
# `.dart_tools/package_config.json`.
#
# For more info see: https://dart.dev/go/dot-packages-deprecation
#
# Generated by pub on 2021-05-04 21:14:02.952939.
async:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib/
boolean_selector:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/
characters:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib/
charcode:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib/
clock:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib/
collection:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib/
cupertino_icons:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.3/lib/
fake_async:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib/
flutter:file:///D:/0.dev.framework/flutter/packages/flutter/lib/
flutter_test:file:///D:/0.dev.framework/flutter/packages/flutter_test/lib/
matcher:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib/
meta:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib/
path:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib/
sky_engine:file:///D:/0.dev.framework/flutter/bin/cache/pkg/sky_engine/lib/
source_span:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.8.0/lib/
stack_trace:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/
stream_channel:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib/
string_scanner:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib/
term_glyph:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib/
test_api:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.19/lib/
typed_data:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib/
vector_math:file:///D:/0.dev.framework/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib/
magic_flutter_app:lib/
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
.png)
한번 알아보시죠... 소스를 까보면(?) 아래와 같습니다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Magic Demo App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
해당 소스는 main.dart 소스 인데요...
해당 소스에서 중점적으로 봐야할 부분에 대해서 알아보시면...
하나, import 구문입니다.
![]()
해당 import 구문은 소스파일에서 사용하려는 패키지를 불러올때 사용하는 구문이기도 합니다.
보통, 다른 dart 클래스 / pubspec.yaml 파일에서 내려 받은 패키지를 불러올때 사용됩니다.참고로, "marterial.dart" 패캐지는 flutter 의 UI 와 관련된 거의 모든 클래스가 포함되어 있기때문에 자주 사용합니다.
.png)
flutter 앱은 C++/JAVA 등등 여러가지의 프로그램들처럼 main() 함수에서 프로그램이 시작됩니다.
우선 샘플프로그램으로 main() 함수가 간단하죠?
runApp() 함수를 호출하고 있네요....
참고로 runApp() 함수는 "binding.dart" 클래스에 정의되어 있고요....flutter 앱을 시작하는 역할을 한다고 보면됩니다.
다시말해서, 해당 함수에서 flutter 앱을 시작하면서 화면에 표시할 위젯을 전달하게 되는데요...
해당 샘플프로그램은 "MyApp" 이라는 위젯을 전달했네요...
MyApp 클래스는 extends 키워드를 통해서 StatelessWidget 를 상속받았고요
.png)
참고로, flutter 에서 앱을 구성하는 위젯은 크게 StatelessWidget / StatefulWidget 로구분되는데요...
해당 내용은 다음에 정리해 볼 블로그에서 좀더 자세하게 다뤄보기로 할거고요...
간단하게 StatelessWidget 는 단어 그대로 상태를 연결할 필요가 없는(내용을 갱신할 필요가 없기때문에..)즉 상태를 감시하고 있을 필요가 없는 위젯를 말하고,
StatefullWidget 는 내용을 갱신하기위해서 상태가 연결된 동적인 위젯을 말합니다.
호기심이 들지만...지금은 간단하게 머릿속에 위와 같이 정리해 두시죠..^^;
그리고, "@override" 어노테이션을 통해서 build() 함수를 재정의 했음을 알 수 있었고요..
해당 build() 함수는 어떤 위젯을 만들 것인지를 정의하게됩니다.
소스보시면, "MaterialApp() 함수" 가 있는대요...해당 함수는 쉽게말해서, 화면에 그림을 그리는데 해당 그림을 위한 도화지라고 머릿속에 넣어두시면됩니다.
해당 함수에서는 그림을 그리는 도구에 속하는 title / theme / home 등등이 정의되어 있습니다.
간단하게 해당 내용을 정리하자면 아래와 같습니다.
title : 앱의 이름
theme : 해당 앱의 테마의 색상
home : 앱을 실행할경우, 첫화면에 표시할 내용
아쉽지만..오늘 블로그는 여기까지입니다.
그럼 결론을 정리해보겠습니다.
이제까지 플러터(Flutter) 프로젝트관련 디렉토리 및 파일 구조에 대해서 설명을 드렸는데요...
어떻게 도움이 되셨는지 모르겠습니다..최대한 쉽게 설명드리려고 노력했으나....^^; 블로그를 작성하면 할 수록 어떻게 하면, 보다 쉽게 정보들을 전달할 수 있을것인가 고민을 많이하게 되네요...
아무튼, 앞으로도 더욱 열심히 노력하는 제가 되도록 노력하겠습니다.
오늘도 마지막까지 제 글을 끝까지 읽어주셔서 진심으로 감사드리고, 제 글이 조금이라도 여러분의 각자의 삶을 살아가시는데 도움이 되셨길 기원합니다.
앞으로도 더욱 좋은 블로그를 남기는 제가 되도록 노력하겠습니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.