安装工具:flutter_windows_v1.9.1+hotfix.6-stable
创建fluterDiv文件夹存放工具包解压
打开环境变量
新增到系统变量的path:
D:\program\fluterDev\flutter\bin
D:\program\fluterDev\flutter\bin\cache\dart-sdk\bin
点击启动文件:D:\program\fluterDev\flutter\flutter_console.bat
命令行运行
flutter doctor
下载jdk,去往oracle官网注册:
https://login.oracle.com/mysso/signon.jsp
创建文件夹:D:\program\fluterDev\javase
里面分别创建文件夹:jdk、jre
首个安装选择jdk文件夹,安装完成选择jre文件夹
检测安装
java -version
添加环境变量
D:\program\fluterDev\javase\jdk\bin
打包命令
keytool
安装勾选去掉,不安装安卓虚拟设备
首次打开选择第二个,更新到最新版本
弹出报错点击取消cancel
下一步,Custom自定义安装
风格选择略过
勾选最后一个Android
切换SDK地址到D:\program\fluterDev\androidsdk
配置下一步,finish
安装完毕configure>sdk Manager
环境变量的系统变量新增:
变量名:ANDROID_HOME
变量值:D:\program\fluterDev\androidsdk
环境变量的系统变量的path编辑-新增:
D:\program\fluterDev\androidsdk\platform-tools
安卓协议
flutter doctor --android-licenses # 一路yes
打开Android Studio的configure的pulgins里面安装Fluter
网易木木模拟器:http://mumu.163.com/
flutter create app_01_test # 创建项目
cd ./app_01_test # 进入项目
flutter doctor # 加载模拟器
flutter run # 运行项目
# 1. 项目 android/build.gradle
repositories {
// 注释添加下面
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
allprojects {
repositories {
// 注释添加下面
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
}
# 2. flutter sdk目录
你的sdk目录\flutter\packages\flutter_tools\gradle
repositories {
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
创建first.dart文件
var lang = 'dart语言';
void main(){
print(lang);
}
运行dart
$ dart first.dart
在web端使用编译
$ dart2js first.dart
lib / dart.main
import 'package:flutter/material.dart';
void main() => runApp(MyDream());
// flutter没有组件都叫部件,flutter由一个个部件组成
// stless 快捷键
class MyDream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
body: Text('data'),
),
);
}
}
import 'package:flutter/material.dart';
void main() => runApp(MyDream());
// flutter没有组件都叫部件,flutter由一个个部件组成
// stless 快捷键
class MyDream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
// 主题颜色
primaryColor: Colors.blue,
// 画布颜色
canvasColor: Colors.red,
),
home: MyDreamPage(),
);
}
}
// 类 快捷键 stful
class MyDreamPage extends StatefulWidget {
@override
_MyDreamPageState createState() => _MyDreamPageState();
}
class _MyDreamPageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Text(''),
);
}
}
import 'package:flutter/material.dart';
void main() => runApp(MyDream());
var title1 = '1';
// flutter没有组件都叫部件,flutter由一个个部件组成
// stless 快捷键
class MyDream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
// 主题颜色
primaryColor: Colors.blue,
// 画布颜色
canvasColor: Colors.red,
),
home: MyDreamPage(),
);
}
}
// 类 快捷键 stful
class MyDreamPage extends StatefulWidget {
final title3 = '导航栏';
@override
_MyDreamPageState createState() => _MyDreamPageState();
}
class _MyDreamPageState extends State {
// const 在类里面要加static
static const title2 = '2';
@override
Widget build(BuildContext context) {
return Scaffold(
// 导航栏
appBar: AppBar(
// title: Text(title1),
title: Text(widget.title3),
),
body: Text(title2),
// 返回顶部
floatingActionButton: FloatingActionButton(
// 事件函数
onPressed: null,
// 按住按键提示
tooltip: '累加',
// 图标
child: Icon(Icons.add),
),
);
}
}
// 类 快捷键 stful
class MyDreamPage extends StatefulWidget {
@override
_MyDreamPageState createState() => _MyDreamPageState();
}
class _MyDreamPageState extends State {
static const title = '导航栏';
int _count = 0;
// 添加函数方法
void _addCount() {
// setState里面写逻辑代码
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Text('$_count'),
// 返回顶部
floatingActionButton: FloatingActionButton(
// 事件函数
onPressed: _addCount,
// 按住按键提示
tooltip: '累加',
// 图标
child: Icon(Icons.add),
),
);
}
}
body: Center(
// 子集,纵向
child: Column(
// 纵向排列方式
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('1'),
Text('2'),
Text('3'),
],
),
),
抽屉
导航
import 'package:flutter/material.dart';
void main() => runApp(MyDream());
class MyDream extends StatefulWidget {
bool colorOffon = false;
@override
_MyDreamState createState() => _MyDreamState();
}
class _MyDreamState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: widget.colorOffon ? Colors.red : Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(
'导航栏',
style: TextStyle(fontSize: 16),
),
// 按钮
actions: [
// 图案图标
IconButton(
icon: Icon(Icons.colorize),
onPressed: () => {
setState(() {
widget.colorOffon = !widget.colorOffon;
})
}),
// 文字图标
IconButton(icon: Icon(Icons.title), onPressed: null)
],
),
// 抽屉-侧拉窗
drawer: Drawer(
child: ListView(
// 设置内边距为0
padding: EdgeInsets.all(0),
children: [
UserAccountsDrawerHeader(
// 头像图片
currentAccountPicture: CircleAvatar(
// NetworkImage 使用网络图片
backgroundImage:
NetworkImage('http://www.webzzw.xyz/static/0.jpg'),
),
// 用户名
accountName: Text('用户名'),
// 邮箱
accountEmail: Text('[email protected]'),
),
],
),
),
body: Text('内容'),
),
);
}
}
抽屉菜单
import 'package:flutter/material.dart';
void main() => runApp(MyDream());
class MyDream extends StatefulWidget {
bool colorOffon = false;
List menuList = ['设置图片', '设置颜色', '跳转'];
@override
_MyDreamState createState() => _MyDreamState();
}
class _MyDreamState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: widget.colorOffon ? Colors.red : Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(
'导航栏',
style: TextStyle(fontSize: 16),
),
// 按钮
actions: [
// 图案图标
IconButton(
icon: Icon(Icons.colorize),
onPressed: () => {
setState(() {
widget.colorOffon = !widget.colorOffon;
})
}),
// 文字图标
IconButton(icon: Icon(Icons.title), onPressed: null)
],
),
// 抽屉-侧拉窗
drawer: Drawer(
child: ListView.builder(
itemCount: widget.menuList.length,
itemBuilder: (BuildContext context, int index) {
// 头像数据
if (index == 0) {
return UserAccountsDrawerHeader(
// 头像图片
currentAccountPicture: CircleAvatar(
// NetworkImage 使用网络图片
backgroundImage:
NetworkImage('http://www.webzzw.xyz/static/0.jpg'),
),
// 用户名
accountName: Text('用户名'),
// 邮箱
accountEmail: Text('[email protected]'),
);
}
// 菜单
return ListTile(
title: Text(widget.menuList[index]),
trailing: Icon(Icons.settings),
);
})),
body: Text('内容'),
),
);
}
}
lib下创建pages页面文件夹,里面创建subPage.dart文件
// main.dart
import 'package:app_01_test/pages/subPage.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyDream());
class MyDream extends StatefulWidget {
bool colorOffon = false;
List menuList = ['设置图片', '设置颜色', '跳转'];
@override
_MyDreamState createState() => _MyDreamState();
}
class _MyDreamState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: widget.colorOffon ? Colors.red : Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(
'导航栏',
style: TextStyle(fontSize: 16),
),
// 按钮
actions: [
// 图案图标
IconButton(
icon: Icon(Icons.colorize),
onPressed: () => {
setState(() {
widget.colorOffon = !widget.colorOffon;
})
}),
// 文字图标
IconButton(icon: Icon(Icons.title), onPressed: null)
],
),
// 抽屉-侧拉窗
drawer: Drawer(
child: ListView.builder(
itemCount: widget.menuList.length,
itemBuilder: (BuildContext context, int index) {
// 头像数据
if (index == 0) {
return UserAccountsDrawerHeader(
// 头像图片
currentAccountPicture: CircleAvatar(
// NetworkImage 使用网络图片
backgroundImage:
NetworkImage('http://www.webzzw.xyz/static/0.jpg'),
),
// 用户名
accountName: Text('用户名'),
// 邮箱
accountEmail: Text('[email protected]'),
);
}
// 菜单,使用事件
return GestureDetector(
onTap: () {
// 跳转页面
Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) {
// 跳转的页面
return SubPage(
id: 1,
title: widget.menuList[index],
);
},
));
},
child: ListTile(
title: Text(widget.menuList[index]),
trailing: Icon(Icons.settings),
),
);
})),
body: Text('内容'),
),
);
}
}
跳转的页面
// subPage.dart
import 'package:flutter/material.dart';
class SubPage extends StatefulWidget {
// 接收其他页面传来的参数
final id;
final title;
// @required 必须传的参数
SubPage({Key key, @required this.id, this.title});
@override
_SubPageState createState() => _SubPageState();
}
class _SubPageState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
),
);
}
}
打开程序运行入口文件main文件
,删掉所有代码,重新构建
// 引入material风格库,是自动按需要引入的
import 'package:flutter/material.dart';
// 入口函数,学过其它语言的同学不陌生,自执行
void main() {
// 最小的Flutter应用程序只是调用runApp()函数与一个小部件,该部件会将其设为小部件树的根部件
// flutter框架根部件会强制根部件覆盖屏幕,这意味着文本“ Hello,world”最终以屏幕为中心
//
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
android目录
这里存放的是Flutter与android原生交互的一些代码
build目录
存储 iOS 和 Android 构建文件
ios目录
这里存放的是Flutter与ios原生交互的一些代码
lib目录
应用源文件,存放的是我们用Dart语言编写程序的源代码
main.dart
应用程序运行入口文件
test目录
测试文件
pubspec.yaml文件
相当其它技术栈框架的package.json文件,是配置项目依赖项的文件,比如配置远程pub仓库的依赖库,或者指定本地资源(图片、字体、音频、视频等)
MaterialApp({
Key key,
this.title = '', // 设备用于为用户识别应用程序的单行描述
this.home, // 应用程序默认路由的小部件,用来定义当前应用打开的时候,所显示的界面
this.color, // 在操作系统界面中应用程序使用的主色。
this.theme, // 应用程序小部件使用的颜色。
this.routes = const {}, // 应用程序的顶级路由表
this.navigatorKey, // 在构建导航器时使用的键。
this.initialRoute, // 如果构建了导航器,则显示的第一个路由的名称
this.onGenerateRoute, // 应用程序导航到指定路由时使用的路由生成器回调
this.onUnknownRoute, // 当 onGenerateRoute 无法生成路由(initialRoute除外)时调用
this.navigatorObservers = const [], // 为该应用程序创建的导航器的观察者列表
this.builder, // 用于在导航器上面插入小部件,但在由WidgetsApp小部件创建的其他小部件下面插入小部件,或用于完全替换导航器
this.onGenerateTitle, // 如果非空,则调用此回调函数来生成应用程序的标题字符串,否则使用标题。
this.locale, // 此应用程序本地化小部件的初始区域设置基于此值。
this.localizationsDelegates, // 这个应用程序本地化小部件的委托。
this.localeListResolutionCallback, // 这个回调负责在应用程序启动时以及用户更改设备的区域设置时选择应用程序的区域设置。
this.localeResolutionCallback, //
this.supportedLocales = const [Locale('en', 'US')], // 此应用程序已本地化的地区列表
this.debugShowMaterialGrid = false, // 打开绘制基线网格材质应用程序的网格纸覆盖
this.showPerformanceOverlay = false, // 打开性能叠加
this.checkerboardRasterCacheImages = false, // 打开栅格缓存图像的棋盘格
this.checkerboardOffscreenLayers = false, // 打开渲染到屏幕外位图的图层的棋盘格
this.showSemanticsDebugger = false, // 打开显示框架报告的可访问性信息的覆盖
this.debugShowCheckedModeBanner = true, // 在选中模式下打开一个小的“DEBUG”横幅,表示应用程序处于选中模式
})
Scaffold是我们布局的主要支撑部件,每一个用户界面都应该有一个Scaffold根部件,通过Scaffold脚手架快速搭建我们的用户界面结构,提供了用于显示drawer、snackbar和底部sheet的API
appBar // 头部导航栏
body // 主体
floatingActionButton // 悬浮按钮
floatingActionButtonLocation // 悬浮按钮位置
floatingActionButtonAnimator // 悬浮按钮动画
persistentFooterButtons // 显示在底部的一组按钮
drawer // 侧拉抽屉菜单
endDrawer // 侧拉抽屉菜单 与上面属性相反
bottomNavigationBar // 显示在底部的导航栏
bottomSheet // 要显示的持久底部工作表
backgroundColor // 背景颜色
resizeToAvoidBottomPadding // 已废弃
resizeToAvoidBottomInset // 为true时:浮动小部件自动调整,以避免弹出键盘时被遮盖
primary 默认true
drawerDragStartBehavior // 默认DragStartBehavior.start
extendBody // 默认false
drawerScrimColor // 抽屉打开时用来遮盖主要内容的涂布颜色
AppBar({
Key key,
this.leading,//在标题前面显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮
this.automaticallyImplyLeading = true,
this.title,//Toolbar 中主要内容,通常显示为当前界面的标题文字
this.actions,//一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单
this.flexibleSpace,//一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样,可以实现一些特殊的效果,该属性通常在 SliverAppBar 中使用
this.bottom,//一个 AppBarBottomWidget 对象,通常是 TabBar。用来在 Toolbar 标题下面显示一个 Tab 导航栏
this.elevation = 4.0,//纸墨设计中控件的 z 坐标顺序,默认值为 4,对于可滚动的 SliverAppBar,当 SliverAppBar 和内容同级的时候,该值为 0, 当内容滚动 SliverAppBar 变为 Toolbar 的时候,修改 elevation 的值
this.backgroundColor,//APP bar 的颜色,默认值为 ThemeData.primaryColor。改值通常和下面的三个属性一起使用
this.brightness,//App bar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness
this.iconTheme,//App bar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData.primaryIconTheme
this.textTheme,//App bar 上的文字样式。默认值为 ThemeData.primaryTextTheme
this.primary = true,
this.centerTitle,//标题是否居中显示,默认值根据不同的操作系统,显示方式不一样,true居中 false居左
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
})
左侧抽屉
// appBar 同级
drawer: Drawer(
child: ListView(
children: [
UserAccountsDrawerHeader(
accountName: Text('Zzw'),
accountEmail: Text('[email protected]'),
currentAccountPicture: CircleAvatar(
backgroundImage:
NetworkImage('http://www.webzzw.xyz/static/4.jpg'),
),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('http://www.webzzw.xyz/static/2.jpg'),
fit: BoxFit.cover,
),
),
),
ListTile(
onTap: () {},
title: Text('用户反馈'),
trailing: Icon(Icons.feedback),
),
ListTile(
onTap: () {},
title: Text('系统设置'),
trailing: Icon(Icons.settings),
),
ListTile(
onTap: () {},
title: Text('文章发布'),
trailing: Icon(Icons.send),
),
// 分割线
Divider(
color: Colors.blue,
),
ListTile(
onTap: () {},
title: Text('退出'),
trailing: Icon(Icons.exit_to_app),
),
],
),
),
打开抽屉方法
import 'package:flutter/material.dart';
class StudyDrawer extends StatelessWidget {
// 抽屉key
GlobalKey _globalKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
// 添加状态key
key: _globalKey,
appBar: AppBar(
title: Text('抽屉'),
centerTitle: true,
),
drawer: Drawer(...),
body: IconButton(
icon: Icon(Icons.open_in_new),
onPressed: () {
// 打开抽屉
_globalKey.currentState.openDrawer();
},
),
);
}
}
右侧自定义抽屉
// appBar 同级
endDrawer: Container(
width: 300,
color: Colors.pinkAccent,
child: Column(
children: [
UserAccountsDrawerHeader(
accountName: Text('Zzw'),
accountEmail: Text('[email protected]'),
currentAccountPicture: CircleAvatar(
backgroundImage:
NetworkImage('http://www.webzzw.xyz/static/4.jpg'),
),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('http://www.webzzw.xyz/static/2.jpg'),
fit: BoxFit.cover,
// 背景颜色透明
colorFilter: ColorFilter.mode(
Colors.green.withOpacity(0.8),
BlendMode.color,
)),
),
),
],
),
)
android/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.movies">
<application
android:name="io.flutter.app.FlutterApplication"
android:label="movies"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
application>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
manifest>
创建 keystore
$ keytool -genkey -v -keystore 英文名.keystore -alias 别名 -keyalg RSA -keysize 2048 -validity 10000 -storepass 密码 -keypass 密码
例:
$ keytool -genkey -v -keystore article.keystore -alias article -keyalg RSA -keysize 2048 -validity 10000 -storepass article -keypass article
引用应用程序中的keystore,生成的 英文名.keystore 文件放到 android/app/下
创建一个名为/android/key.properties
的文件,其中包含对密钥库的引用
# /android/key.properties
storePassword=密码
keyPassword=密码
keyAlias=别名
storeFile=英文名.keystore
通过编辑/android/app/build.gradle文件为您的应用配置签名
替换:
android {
为:
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
替换:
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
}
}
为:
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
切换到项目根目录
$ flutter build apk
打包好的发布APK位于/build/app/outputs/apk/app-release.apk