是的,我们新建一个Flutter程序。
本来想跟这个世界说声Hello,Flutter想告诉人们
需要好好赚钱,所以给你了你一个计数器。
一、所有Flutter人都知道的计数器
Android studio 新建一个Flutter项目。
你会看到如下代码
如果运行不起来报错,很大可能是gradle版本问题,新建一个普通的安卓项目,看一下gradle的信息
classpath 'com.android.tools.build:gradle:7.1.1'
distributionUrl=https://services.gradle.org/distributions/gradle-7.2-all.zip
找到这两个gradle配置的版本号,对应修改一下Flutter的信息。
原本
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// 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: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required 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
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
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: <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),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
中文版
emm,英文下,好像有点不太亲切,那么就改成中文吧
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// 这个小部件是你应用程序的根部件。
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter演示',
theme: ThemeData(
// 这是你应用程序的主题。
//
// 尝试用 "flutter run" 运行你的应用程序。
// 你会看到应用程序有一个蓝色的工具栏。
// 然后,在不退出应用程序的情况下,尝试将 primarySwatch 更改为 Colors.green,
// 然后触发 "热重载"(在你运行 "flutter run" 的控制台中按下 "r"),
// 或者直接保存更改以进行 "热重载"(在 Flutter IDE 中)。
// 注意,计数器没有重置为零;应用程序并没有重新启动。
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter演示主页'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
// 这个小部件是你应用程序的主页。它是有状态的,意味着它有一个包含影响外观的字段的 State 对象(在下面定义)。
// 这个类是状态的配置。它保存了父级(在本例中是 App 小部件)提供的值(在本例中是标题),
// 并且由 State 的 build 方法使用。小部件子类中的字段始终标记为 "final"。
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// 这个对 setState 的调用告诉 Flutter 框架状态发生了变化,
// 这导致重新运行下面的 build 方法,以便显示可以反映更新后的值的内容。
// 如果我们在不调用 setState() 的情况下更改 _counter,
// 那么 build 方法将不会再次被调用,因此似乎什么也没有发生。
_counter++;
});
}
@override
Widget build(BuildContext context) {
// 每次调用 setState(例如由 _incrementCounter 方法调用)时,都会重新运行这个方法。
//
// Flutter 框架经过优化,使得重新运行 build 方法非常快速,
// 所以你只需要重建需要更新的内容,而不必逐个更改小部件的实例。
return Scaffold(
appBar: AppBar(
// 这里我们从由 App.build 方法创建的 MyHomePage 对象中取得值,并将其用作我们的 appbar 标题。
title: Text(widget.title),
),
body: Center(
// Center 是一个布局小部件。它接受一个单独的子部件并将其放置在父部件的中间位置。
child: Column(
// Column 也是一个布局小部件。它接受一个子部件列表并垂直地排列它们。
// 默认情况下,它会水平地调整自身大小以适应其子部件,
// 并尝试尽量与其父部件一样高。
//
// 调用 "debug painting"(在控制台中按下 "p",在 Android Studio 中选择 Flutter Inspector 中的 "Toggle Debug Paint" 操作,
// 或在 Visual Studio Code 中选择 "Toggle Debug Paint" 命令),
// 可以看到每个小部件的线框。
//
// Column 有各种属性来控制其自身的大小和其子部件的位置。
// 在这里,我们使用 mainAxisAlignment 来垂直居中子部件;
// 这里的主轴是垂直轴,因为 Column 是垂直的(交叉轴将是水平的)。
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'你已经按下按钮的次数:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: '增加',
child: const Icon(Icons.add),
), // 这个尾逗号使得构建方法的自动格式更加友好。
);
}
}
但是
但是
但是
但是
但是
但是
emm,看起来是舒服一些,但是又感觉太长了
简单版
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// 这个小部件是你应用程序的根部件。
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter演示',
theme: ThemeData(
// 这是你应用程序的主题。
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter演示主页'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'你已经按下按钮的次数:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: '增加',
child: const Icon(Icons.add),
), // 这个尾逗号使得构建方法的自动格式更加友好。
);
}
}
嗯,往简单了说,main是入口,启动了app,MyHomePage就是页面。
哇,简单,哇完事,哇,完结撒花。
二、两两三三概念事,最简单也最困难
程序根入口是main
- Flutter 应用中
main函数为应用程序的入口。main函数中调用了runApp方法,它的功能是启动Flutter应用。runApp它接受一个Widget参数,在本示例中它是一个MyApp对象,MyApp()是 Flutter 应用的根组件。
全世界都是widget
MyApp类代表 Flutter 应用,它继承了StatelessWidget类,这也就意味着应用本身也是一个widget。- 在 Flutter 中,大多数东西都是 widget(后同“组件”或“部件”),包括对齐(Align)、填充(Padding)、手势处理(GestureDetector)等,它们都是以 widget 的形式提供。
- Flutter 在构建页面时,会调用组件的
build方法,widget 的主要工作是提供一个 build() 方法来描述如何构建 UI 界面(通常是通过组合、拼装其他基础 widget )。 MaterialApp是Material 库中提供的 Flutter APP 框架,通过它可以设置应用的名称、主题、语言、首页及路由列表等。MaterialApp也是一个 widget。