前章の終わりに Flutter プロジェクトを作成しました。今回はその中身がどのようなディレクトリ構成になっているのか、また沢山あるファイルの中でよく使うファイルとその用途を簡単に解説していきます。
ディレクトリ構成
前章のflutter create
コマンドで以下のようなディレクトリ構成のプロジェクトが作成されたかと思います。
.
├── README.md
├── analysis_options.yaml
├── android
├── ios
├── lib
│ └── main.dart
├── linux
├── macos
├── pubspec.lock
├── pubspec.yaml
├── test
├── test_flutter.iml
├── web
└── windows
lib
ディレクトリ
実際のアプリのコードを記述していくディレクトリです。lib
ディレクトリ内にある main.dart
というファイルが Flutter アプリのエントリーポイントとなるファイルになります。
analysis_options.yaml
ファイル
analisys_options.yaml
は Dart のコードを解析する際の設定ファイルです。Flutter のコードを解析する際にはこのファイルの設定を参照します。
Platform ごとのディレクトリ
ios
、android
、web
、macos
、linux
、windows
はそれぞれ Platform ごとのディレクトリです。lib
ディレクトリに記述されたコードを各種 platform に対応したコードに変換する際に参照されます。
パッケージ管理ファイル
pubspec.yaml
と pubspec.lock
は Flutter のパッケージ管理に関するファイルです。pubspec.yaml
にはパッケージの依存関係を記述し、pubspec.lock
にはその依存関係を解決した結果が記述されます。
javascript などで言うところのpackage.json
とpackage-lock.json
に近いですね。
test
ディレクトリ
お察しの通り、Flutter のテストコードを記述するディレクトリです。
その他
[プロジェクト名].iml
となっているファイルは 開発に IntelliJ IDEA を使う際に必要なファイルです。
ファイルの中身
全ては紹介できませんが、一部よく使うファイルについてだけ軽くご紹介させていただきます。
main.dart
main.dart
は前述の通り、アプリのエントリーポイントとなるファイルです。
特に指定がなければflutter run
を実行するとこのファイルが実行されます。こちらのファイルの中身についてはまた後ほど詳しく見ていきます。
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
pubspec.yaml
pubspec.yaml
は プリケーションのバージョン管理や依存パッケージの管理などアプリケーションに関する設定を記述するファイルです。
前章で紹介したflutter pub add
で依存パッケージをインストールするとこのファイル内のdependencies
に追記されます。
また画像などのアセットファイルを追加する際もこのファイル内のflutter
以下にアセットファイルのパスを記述することでアクセスできるようになります。
pubspec.yaml
name: test_flutter
description: A new Flutter project.
publish_to: "none"
version: 1.0.0+1
environment:
sdk: ">=2.17.6 <3.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
+ assets:
+ - assets/my_icon.png
+ - assets/background.png
ios
ディレクトリ内
ios/Runner/AppDelegate.swift
iOS 特有の機能などを使う場合には iOS 側に処理の実装が必要な場合があります。その場合はこのファイルに実装を記述します。
AppDelegate.swift
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
ios/Runner/Info.plist
位置情報の取得や BlueTooth の使用などユーザーに許可を求める機能を使う場合などにこのファイルに設定を記述します。
info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Test Flutter</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>test_flutter</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
android
ディレクトリ内
android/app/build.gradle
Android のアプリケーションに関する設定ファイルです。コンパイルに使う SDK のバージョンやアプリケーションの設定などを記述します。
使用するパッケージによってはネイティブ側にも依存関係の設定が必要な場合があり、そのような際にはこのファイルに変更を加えることがあります。
app/build.gradle
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.test_flutter"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
android/app/src/main/AndroidManifest.xml
位置情報の取得や BlueTooth の使用などユーザーに許可を求める機能を使う場合などにこのファイルに設定を記述します。
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test_flutter">
<application
android:label="test_flutter"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
まとめ
今回は生成された Flutter プロジェクトの構成とその中でも重要なファイルの役割についてピックアップして説明しました。
次章から早速サンプルアプリの解説!...と行きたいところですが、その前にまず Flutter を理解する上で重要な概念についてご紹介していきたいと思います。