Android Studio creates the first Flutter project

1. Create a Flutter project

1.1 file->New–>New Flutter Project

Insert image description here

1.2 Configure Flutter SDK Path

Insert image description here

1.3 Fill in project related information

Insert image description here

2. Detailed explanation of opening the project panel in android studio

Insert image description here

2-1 Compile and run module control area (1, 2, 3, 4, 5)

1: Running platform, since I am not connected to a mobile device, I chose the chrome browser to run
Insert image description here
2: Running source code module
3: Start running button
4: Hot update button
5: Pause button
Insert image description here

2-2 View layout tree

Flutter widget inspector is a powerful tool for visualizing and viewing widget trees.

The Flutter framework layer uses widgets as the core building blocks to handle everything from controls (such as text, buttons, toggles, etc.) to layout (such as centering, padding, rows and columns, etc.).

Flutter inspector not only helps you visually view the Flutter widget tree, but also has other functions: understanding the existing layout
and diagnosing layout problems.
Insert image description here

2-3 Flutter project structure

|--flutter_hello -项目名称
   |--pubspec.yaml  -管理第三方库以及资源的配置文件
   |--android       -android原生工程
   |--ios           -IOS原生工程
   |--lib           -flutter源文件目录
      |--main.dart  -flutter入口文件

Insert image description here

2-3-1 pubspec.yaml

pubspec.yaml is the configuration file of the Flutter project, similar to the Gradle configuration file in Android. Let's take a look at the configuration of each attribute in pubspec.yaml.

name: flutter_hello
description: A new Flutter project.

# The following line prevents the package from being accidentally published to
# pub.dev using `flutter 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 is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=2.18.2 <3.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
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

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^2.0.0

# 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 packages.
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

The default configuration in the project, remove the comments, and the remainder is as follows:

name: flutter_hello
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
  sdk: '>=2.18.2 <3.0.0'
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0
  
flutter:
  uses-material-design: true

name

This attribute represents the package name. This attribute is very important. You need to use this package name when introducing other files:

description

The description attribute is an optional configuration attribute and is an introduction to the current project. The content is actually what we declared when we created the project.

publish_to

This line prevents the software package from being published to pub.dev by pub publish. This line is a required configuration for private software packages; you can also delete this line if you want to publish the current software package to pub.dev.

version

This property is the version and build number of the application, in the format xxx+x.
version number : + the front part, separated by 2 small dots,
build number : + the back part.
In Android, version number corresponds to versionName, and build number corresponds to versionCode. There are related configurations under android/build.gradle:
Insert image description here

environment

Add Flutter and Dart version control under the Environment property.

environment:
  sdk: '>=2.18.2 <3.0.0'

The above version stipulates that this application or library can only run on Dart SDK versions higher than or equal to 2.18.2 and lower than 3.0.0.

We can also add the Flutter version manually:

environment:
  sdk: ">=2.18.2 <3.0.0"
  flutter: "3.3.4"

dependencies

Contains packages that the application depends on and will be compiled into the project

1. Depend on third-party libraries on pub.dev

Relying on third-party libraries on pub.dev is the most common way

dependencies:
  transmogrify: ^1.4.0
2. Rely on your own warehouse

You can use hosted to specify the path to the warehouse. Version constraints are optional but recommended. If no version constraint is given, any is assumed.

environment: 
  sdk: >=2.15.0 < 3.0.0

dependencies:
  transmogrify:
    hosted: https://some-package-server.com
    version: ^1.4.0

If your package has a pre-2.15 language version, you must use the more verbose hosting format

environment:
  sdk: >=2.14.0 < 3.0.0

dependencies:
  transmogrify:
    hosted:
      name: transmogrify
      url: https://some-package-server.com
    version: ^1.4.0
3. Depend on Git repository
dependencies:
  kittens:
    git: https://github.com/munificent/kittens.git

If you want to depend on a specific commit, branch or tag, add the ref key in the description

dependencies:
  kittens:
    git:
      url: https://github.com/munificent/kittens.git
      ref: some-branch
4. Depend on local libraries
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

dev_dependencies

dev_dependencies are only packages during runtime

flutter

Flutter related configuration, assets resources, fonts fonts

1. Configuration of picture resources

1-1. Create an images directory at the same level as the configuration file.

Insert image description here
1-2. Configure in pubspec.yaml

 assets:
     - images/flutter.jpg

1-3. Use AssetImage to introduce resources

AssetImage("images/flutter.jpg")

Insert image description here

2. Configuration of multi-resolution images

2-1. Picture resources
. General picture resources
Insert image description here
. Pictures with 2.0x screen density. Pictures
Insert image description here
with 3.0x screen density.
Insert image description here
2-2. Configuration of picture resources.

  assets:
     - images/flutter.jpg
     - images/2.0x/flutter.jpg
     - images/3.0x/flutter.jpg

2-3. Application of image resources

const Image(image: AssetImage("images/flutter.jpg"))

2-4. Picture resources displayed on devices with different resolutions

2-4-1. VIVO X20A mobile phone: Screen resolution 1080x2160 Screen density: 480
Use adb shell wm size to check the device resolution

adb shell wm size

Insert image description here
Use adb shell wm density to view device screen density

adb shell wm density

Insert image description here
Insert image description here
PS: You can see that the device loads pictures under 3.0x

2-4-2. Android7.0 device: Screen resolution 1366x768 Screen density: 160
Insert image description here
Insert image description here
PS: You can see that the device loads images with a common density

Screen density
I don’t know how to define screen density. In fact, screen density is another representation of pixel density, which is based on 160dpi=1.0. After the mobile phone leaves the factory, the screen density, including the pixel density in the X and Y axis directions, is a fixed value.
Android divides the actual screen densities (low, medium, high, and extra high, extra extra high)
into ordinary screens: ldpi is 120dpi, mdpi is 160dpi, hdpi is 240dpi, xhdpi is 320dpi, and xxhdpi is 480dpi.
Android divides the screen based on the pixel density of 160dpi. When the pixel density is 160dpi, the screen density is 1.0, when the pixel density is 120dpi, the screen density is 0.75, and when the pixel density is 320dpi, the screen density is 2.0.

name density multiple
ldpi 120dpi 0.75x
mdpi 160dpi 1x
hdpi 240dpi 1.5x
xhdpi 320dpi 2.0x
xxhdpi 480dpi 3.0x
xxxhdpi 640dpi 4.0x

3. Font resource configuration

3-1.
Font libraries currently supported by flutter

  • .ttf
  • .ttc

  • Font libraries not supported by .otf :
  • .woff
  • woff2

3-2. Download the font library (Google's font library https://fonts.google.com/) and copy it to the project
Insert image description here
3-3. Configure it in pubspec.yaml

 fonts:
   - family: Niramit
     fonts:
       - asset: fonts/Niramit-BoldItalic.ttf

Insert image description here
3-4. Global use
Set the fontFamily attribute of them in MaterialApp

 fontFamily: "Niramit",

Insert image description here
Insert image description here
Set the font for local controls:
configured in pubspec.yaml

- family: Pacifico
      fonts:
        - asset: fonts/Pacifico-Regular.ttf

Insert image description here

style: TextStyle(fontFamily: "Niramit")

Insert image description here
Insert image description here

2-3-2 android native project

|--android
   |--build.gradle             -项目构建的gradle文件
   |--settings.gradle          -包含整个工程的所有 Module 的声明
   |--gradle.properties        -属性是全局的,可以在各个模块的build.gradle里面直接引用
   |--local.properties         -常用来声明sdk、ndk的路径
   |--app                      -app模块
      |--build.gradle          -app模块的gradle文件
      |--CMakeLists.txt        -app模块下cpp文件编译配置
      |--lib                   -app模块依赖的第三方jar包
      |--src                   -app模块源码
         |--main
            |--AndroidMenifest.xml   -app模块的menifest文件
            |--assets                -本地文件
            |--cpp                   -c或者cpp源码
            |--fonts                 -字体库文件
            |--java                  -源码
            |--jniLibs               -第三方so库文件
            |--res                   -布局、图片、字符、自定义属性、尺寸、颜色值等资源文件

2-3-2-1 android/build.gradle

buildscript {
    
    
    ext.kotlin_version = '1.6.10'  //声明kotlin版本
    repositories {
    
                     //声明依赖的仓库
        google()
        mavenCentral()
    }

    dependencies {
    
                    //声明gradle依赖的版本
        classpath 'com.android.tools.build:gradle:7.1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    
                       //所有模块依赖的仓库
    repositories {
    
    
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    
    
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    
    
    project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
    
    
    delete rootProject.buildDir      //删除根目录下的buildDir文件夹任务
}

There are repositories and dependencies in both buildscript and allprojects. The difference between the two is that the configuration in buildscript mainly serves gradle itself . Some libraries that the gradle plug-in needs to depend on are configured here, while allprojects serves all modules in the project. Common modules for configuration .

2-3-2-2 settings.gradle

include ':app'

def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()

assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }

def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

1. Use include to declare the modules included in the project.

2-3-2-3 gradle.properties

org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

1. org.gradle.jvmargs=-Xmx1536M
jvm heap memory size
1-1. Heap size setting (XX type parameter)
Initialization heap memory: -XX:InitialHeapSize=1024m (-Xms1024m - abbreviation)
Maximum heap memory: -XX:MaxHeapSize =1024m (-Xmx1024m - abbreviation)
1-2. -Xss: Thread stack size : -Xss defaults to 512k~1024k, which is equivalent to -XX:ThreadStackSize=512k. A value equal to zero indicates that the default value is used. Under normal circumstances, there is no need to set
1-3, -Xmn: Set the young generation size . The entire heap size = young generation size + old generation size + persistent generation size. The persistent generation generally has a fixed size of 64m, so increasing the young generation will reduce the size of the old generation. This value has a great impact on system performance. Sun officially recommends configuring it to 3/8 of the entire heap.
1-4. Metaspace-XX:MetaspaceSize : The initialized Metaspace size, which controls the threshold for GC in the metaspace. After GC, dynamically increase or decrease MetaspaceSize. By default, this value ranges from 12M to 20M depending on the platform.
-XX:MaxMetaspaceSize: Limit the upper limit of Metaspace growth to prevent Metaspace from unlimited use of local memory due to certain circumstances, affecting other programs
1-5, -XX:NewRatio new generation (Eden + 2*S) and old generation (not The ratio (including the permanent area). For example, -XX:NewRatio=4 means that the new generation: the old generation = 1:4, that is, the old generation accounts for 4/5 of the entire pair; default value = 2
1-6, -XX:SurvivorRatio: the ratio of two Survivor areas and Eden area. For example: -XX:SurvivorRatio=8 means two Survivor areas: Eden area=2:8, each Survivor accounts for 1/10; JVM default = 8

2. android.useAndroidX=true
means "the Android plug-in will enable the corresponding AndroidX library instead of the Support library"; if not set, the default is false;

3. android.enableJetifier=true
means that the Android plug-in will automatically migrate existing third-party libraries (aar packages or jar packages and other dependent libraries) by rewriting their binary files to migrate AndroidX dependencies; if not set, the default is false ;

gradle.properties common function configuration

org.gradle.jvmargs=-Xmx5120m -XX:MaxPermSize=1280m -Dfile.encoding=UTF-8
#(JVM堆内存大小,要是想运行的快一些,就改大点,整个8192m啥的)
 
org.gradle.daemon=true
#通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,
#而不是重新 fork 一个 gradle构建进程
 
org.gradle.configureondemand=true 
#按需加载
 
org.gradle.parallel=true 
#并行编译
 
org.gradle.caching=true 
#开启 gradle 缓存
 
android.enableBuildCache=true
#开启依赖缓存,这个设置可以让Android Studio 会把依赖的 jar 或 arr 缓存到本地,并且把模块名称设置为 hash 值。每次编译生成的缓存在 $HOME/.android/build-cache
 
android.useAndroidX=true
# 标识当前 module 启用 Androidx ,当把android项目自动迁移到androidX,
AS会自动在这个文件加上这句
 
android.enableJetifier=true
# 表示将项目中使用的第三方库也迁移到 Androidx
 
android.injected.testOnly=false
#解决真机无法安装测试包的报错,因为国内一些安卓手机制作商定制的 
#Android 系统不允许安装含带这个属性的测试包。哪怕你使用 -t 参数通过 adb 安装也是不行的,这个很常见
 
android.useNewApkCreator=false
#声明使用旧的打包器解决 Android Studio 升级 3.6 之后,
#报错 Entry name 'AndroidManifest.xml' collided,
#因此禁用新版本打包工具,使用旧的打包工具
 
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.incremental.js=true
#kotlin 增量编译
 
kotlin.caching.enabled=true
#kotlin 编译缓存
 
kotlin.parallel.tasks.in.project=true
#kotlin 并行编译
 
kotlin.code.style=official
# Kotlin code style for this project: "official" or "obsolete"
 
 
# 优化kapt
# 并行运行kapt1.2.60版本以上支持
kapt.use.worker.api=true
# 增量编译 kapt1.3.30版本以上支持
kapt.incremental.apt=true
# kapt avoiding 如果用kapt依赖的内容没有变化,会完全重用编译内容,省掉#`app:kaptGenerateStubsDebugKotlin`的时间
kapt.include.compile.classpath=false
 

2-3-2-4 local.propertices

sdk.dir=D\:\\Android\\AndroidStudio\\SDK
flutter.sdk=D\:\\Android\\flutter_windows_3.3.4-stable\\flutter
flutter.buildMode=debug
flutter.versionName=1.0.0
flutter.versionCode=1

Declared the paths of sdk and flutter sdk

2-3-2-5 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')

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.flutter_hello"
        // 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"
}

Flutter version information reads script from local.propertices

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')

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    
    
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    
    
    flutterVersionName = '1.0'
}

gradle plugin dependencies

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android compilation and packaging configuration

android {
    
    
    compileSdkVersion flutter.compileSdkVersion    //sdk版本
    ndkVersion flutter.ndkVersion                  //ndk版本

    compileOptions {
    
                                  //Java 编译版本
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
    
                                  //kotlin编译版本
        jvmTarget = '1.8'
    }

    sourceSets {
    
                                    //显式的指定特定的文件和目录,我们利用这个特性来完成代码和资源的灵活配置
        main.java.srcDirs += 'src/main/kotlin'  //显示指定项目java源码路径
    }

    defaultConfig {
    
    
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.flutter_hello"     //应用唯一标识ID,必须保持唯一
        // 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    //应用支持的最小sdk版本
        targetSdkVersion flutter.targetSdkVersion  //应用当前sdk版本
        versionCode flutterVersionCode.toInteger() //应用版本号
        versionName flutterVersionName             //应用版本名称
        multiDexEnabled true                       //支持分包
    }
    
    signingConfigs {
    
    //签名配置
        release {
    
      //正式包的签名配置
            storeFile file("platform.jks")
            storePassword "platform123"
            keyAlias "platform"
            keyPassword "platform123"
        }

        debug {
    
    //测试包的签名配置
            storeFile file("platform.jks") //签名文件
            storePassword "platform123"   //保存密码
            keyAlias "platform"           //别名
            keyPassword "platform123"     //密码
        }

    }
    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.release //使用上面配置的正式环境的签名文件
        }
    }
}

Module dependency configuration management

dependencies {
    
    
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

2-3-2-6 AndroidMenifest.xml

This xml file configures the application components (activity, service, provider, receiver), the application package name, and the permissions required by the application.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.flutter_hello">     //程序包名
   <application
        android:label="flutter_hello"  //程序名称
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"> //程序Icon
        <activity   //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>

2-3-3 IOS native project

2-3-4 lib flutter project

|--lib
   |--main.dart                     -flutter入口文件
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
    
    
  const MyApp({
    
    super.key});
  
  Widget build(BuildContext context) {
    
    
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        fontFamily: "Pacifico",
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
    
    
  const MyHomePage({
    
    super.key, required this.title});
  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:',
                style: TextStyle(fontFamily: "Niramit")
            ),
            Text(
              '$_counter',
              style: const TextStyle(fontFamily: "Niramit")
            ),
            const Image(image: AssetImage("images/flutter.jpg"))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), 
    );
  }
}

runApp

void runApp(Widget app) {
    
    
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

Bind the app to the root component

MyApp

class MyApp extends StatelessWidget {
    
    
  const MyApp({
    
    super.key});
  
  Widget build(BuildContext context) {
    
    
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        fontFamily: "Pacifico",
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

MyApp inherits from StatelessWidget, which is the base class of stateless components. As the root component of the page, it generally does not need to refresh the UI globally, so stateless components are usually used to improve UI construction performance. The last component built by MyApp is MaterialApp. MaterialApp is a component that supports Android material design effects . CupertinoApp is usually used on IOS. CupertinoApp is a component that supports IOS design style ; there is also WidgetsApp, which is a component with normal effects.

Related properties supported by MaterialApp:

const MaterialApp({
    
    
    super.key,
    this.navigatorKey,//导航键
    this.scaffoldMessengerKey,//脚手架键
    this.home,//主页
    Map<String, WidgetBuilder> this.routes = const <String, WidgetBuilder>{
    
    },//应用程序顶级路由表
    this.initialRoute,//如果构建了导航器,则会显示第一个路由的名称
    this.onGenerateRoute,//路由管理拦截器
    this.onGenerateInitialRoutes,//生成初始化路由
    this.onUnknownRoute,//当onGenerateRoute无法生成路由时调用
    List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],//创建导航器的观察者列表
    this.builder,//在导航器上面插入小部件
    this.title = '',//程序切换时显示的标题
    this.onGenerateTitle,//程序切换时生成标题字符串
    this.color,//颜色
    this.theme,//页面主题
    this.darkTheme,//深色主题
    this.highContrastTheme,//系统请求“高对比度”使用的主题
    this.highContrastDarkTheme,//系统请求“高对比度”暗黑模式下使用的主题颜色
    this.themeMode = ThemeMode.system,//使用哪种模式的主题(默认跟随系统)
    this.locale,//初始区域设置
    this.localizationsDelegates,//本地化代理
    this.localeListResolutionCallback,//失败或未提供设备的语言环境
    this.localeResolutionCallback,//负责计算语言环境
    this.supportedLocales = const <Locale>[Locale('en', 'US')],//本地化地区列表
    this.debugShowMaterialGrid = false,
    this.showPerformanceOverlay = false,
    this.checkerboardRasterCacheImages = false,//打开栅格缓存图像的棋盘格。
    this.checkerboardOffscreenLayers = false,//打开渲染到屏幕外位图的层的棋盘格
    this.showSemanticsDebugger = false,
    this.debugShowCheckedModeBanner = true,
    this.shortcuts,
    this.actions,
    this.restorationScopeId,
    this.scrollBehavior,//可滚动小部件的行为方式
    this.useInheritedMediaQuery = false,//
  })

MyHomePage

class MyHomePage extends StatefulWidget {
    
    
  const MyHomePage({
    
    super.key, required this.title});
  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:',
                style: TextStyle(fontFamily: "Niramit")
            ),
            Text(
              '$_counter',
              style: const TextStyle(fontFamily: "Niramit")
            ),
            const Image(image: AssetImage("images/flutter.jpg"))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Because the demo function is to click the '+' sign, it will have the effect of increasing the number, and the UI needs to change , so MyHomePage inherits StatefulWidget and rebuilds the control by calling the setState method.

Scaffold

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:',
                style: TextStyle(fontFamily: "Niramit")
            ),
            Text(
              '$_counter',
              style: const TextStyle(fontFamily: "Niramit")
            ),
            const Image(image: AssetImage("images/flutter.jpg"))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

In fact, the top-level page constructed from the overall page of MyHomePage is Scaffold. What is Scaffold? The following content is derived from source code interception

/// Implements the basic Material Design visual layout structure.实现了基本的 Material Design 视觉布局结构。
///
/// This class provides APIs for showing drawers and bottom sheets. 此类提供用于显示抽屉和底页的 API。

/// The Scaffold is designed to be a top level container for
/// a [MaterialApp]. This means that adding a Scaffold
/// to each route on a Material app will provide the app with
/// Material's basic visual layout structure.

///Scaffold是作为MaterialApp的顶级容器而设计的。这就意味着为每一个Material app的页面添加一个Scaffold组件后,
///就会为应用提供了Material Design 视觉布局结构

PS: Actually, it’s just one sentence: MaterialApp and Scaffold must be used together.

Properties supported by Scaffold

const Scaffold({
    
    
    super.key,
    this.appBar,//页面上方导航条
    this.body,//页面主体
    this.floatingActionButton,//悬浮按钮
    this.floatingActionButtonLocation,//悬浮按钮位置
    this.floatingActionButtonAnimator,//悬浮按钮动画
    this.persistentFooterButtons,//显示在底部导航条上方的一组按钮
    this.persistentFooterAlignment = AlignmentDirectional.centerEnd,
    this.drawer,//左侧抽屉菜单
    this.onDrawerChanged,//抽屉菜单改变的回调监听
    this.endDrawer,//右侧抽屉菜单
    this.onEndDrawerChanged,//右侧抽屉菜单改变回调监听
    this.bottomNavigationBar,//底部导航条
    this.bottomSheet,//个持久停留在body下方,底部控件上方的控件
    this.backgroundColor,//背景色
    this.resizeToAvoidBottomInset,
    this.primary = true,//是否在屏幕顶部显示Appbar, 默认为 true,Appbar 是否向上延伸到状态栏,如电池电量,时间那一栏
    this.drawerDragStartBehavior = DragStartBehavior.start,//控制 drawer 的一些特性
    this.extendBody = false,//body 是否延伸到底部控件
    this.extendBodyBehindAppBar = false,//默认 false,为 true 时,body 会置顶到 appbar 后,如appbar 为半透明色,可以有毛玻璃效果
    this.drawerScrimColor,//侧滑栏拉出来时,用来遮盖主页面的颜色
    this.drawerEdgeDragWidth,//侧滑栏拉出来的宽度
    this.drawerEnableOpenDragGesture = true,//左侧侧滑栏是否可以滑动
    this.endDrawerEnableOpenDragGesture = true,//右侧侧滑栏是否可以滑动
    this.restorationId,
  })

Guess you like

Origin blog.csdn.net/u011557841/article/details/127258302