本文详细介绍了Flutter框架的基本概念、优势和应用场景,并提供了环境搭建和基础语法的学习指南。此外,文章还涵盖了常用Widget的使用方法以及响应式编程与事件处理等内容,帮助读者全面理解和掌握Flutter开发。文中还提供了丰富的实战案例和项目构建发布的指导,是学习Flutter语法资料的绝佳资源。
引入Flutter框架 1. Flutter框架的基本概念Flutter是由Google开发的一个开源UI框架,它允许开发者使用一套代码库为iOS和Android开发高质量的原生应用。Flutter的核心理念是“快速开发、高效渲染”。这意味着开发者可以快速构建出美观且性能优秀的应用程序。
Flutter使用Dart语言作为开发语言,提供了丰富的Widget库。Widget是Flutter中的基本构建单元,用Widget来构建出各种用户界面。
2. Flutter的优势和应用场景优势
- 快速开发:Flutter提供了一套完整的开发工具链,包括热重载(Hot Reload)功能,使得开发者可以在开发过程中快速看到修改的效果,极大地提高了开发效率。
- 高性能:Flutter使用自己的渲染引擎,可以实现60帧的流畅动画效果,并且能够直接调用原生平台的性能优化。
- 跨平台:使用一套代码库即可同时开发iOS和Android应用,减少了学习成本和开发时间。
- 丰富的组件库:Flutter内置了大量的组件库,包括常用的Text、Button、ListView等,可以满足大部分开发需求。
- 定制性强:开发者可以自定义Widget,以满足特定的设计需求。
应用场景
- 社交应用:如微博、微信等,需要快速迭代和良好的用户体验
- 电商应用:如淘宝、京东等,需要丰富的交互效果和高效的渲染性能
- 企业应用:如ERP、CRM等,需要稳定可靠且跨平台的解决方案
安装Flutter SDK
- 下载Flutter SDK:访问Flutter官网(https://flutter.dev/)并下载对应操作系统的安装包。
- 解压安装包:将下载的包解压到指定目录。
- 配置环境变量:将Flutter SDK的路径添加到环境变量PATH中。
示例代码:
# 解压安装包
tar -xvf flutter_macos_2.10.3-stable.tar.xz -C ~/development/
# 配置环境变量
export PATH="$PATH:~/development/flutter/bin"
安装Dart SDK
Flutter依赖于Dart SDK,因此也需要安装Dart SDK。
- 下载Dart SDK:访问Dart官网(https://dart.dev/)并下载对应操作系统的安装包。
- 解压安装包:将下载的包解压到指定目录。
- 配置环境变量:将Dart SDK的路径添加到环境变量PATH中。
示例代码:
# 解压安装包
tar -xvf dart-sdk-2.14.4.tar.gz -C ~/development/
# 配置环境变量
export PATH="$PATH:~/development/dart-sdk/bin"
安装IDE
为了开发Flutter应用,推荐使用以下IDE之一:
- Visual Studio Code:安装Flutter插件后即可使用。
- Android Studio:安装Flutter插件后即可使用。
安装模拟器
为了测试Flutter应用,需要安装Android和iOS的模拟器。
- 安装Android Studio并配置AVD(Android Virtual Device)。
- 安装Xcode并配置iOS模拟器。
示例代码:
# 安装Android Studio并配置AVD(Android Virtual Device)
# 打开Android Studio,进入AVD Manager创建模拟器
# 安装Xcode并配置iOS模拟器
# 打开Xcode,进入Preferences -> Components下载iOS模拟器镜像
创建第一个Flutter项目
- 打开终端或命令行工具。
- 运行以下命令来创建一个新的Flutter项目:
flutter create first_flutter_app
cd first_flutter_app
flutter run
以上命令会在当前目录创建一个名为first_flutter_app
的Flutter项目,并运行项目。
1.1 变量与类型
Dart是一门面向对象的编程语言,支持多种数据类型,包括基本类型和复杂类型。
基本类型
- 整型(int):表示整数。
- 浮点型(double):表示带有小数部分的数字。
- 布尔型(bool):表示真(true)或假(false)。
- 字符串(String):表示文本。
- 符号(Symbol):表示符号名称。
- 空(Null):表示空值。
复杂类型
- List:表示列表(数组)。
- Map:表示映射(字典)。
- Set:表示集合。
- Function:表示函数。
- Class:表示自定义类型。
1.2 变量赋值
在Dart中,可以使用var
、final
和const
关键字来声明变量。
var age = 25; // 使用var声明变量
final name = 'John'; // 使用final声明不可更改的变量
const PI = 3.14; // 使用const声明编译时常量
1.3 函数定义与调用
函数可以定义一个特定的任务,接受输入参数,并返回一个结果。
int add(int a, int b) {
return a + b;
}
int result = add(3, 5); // 调用函数
print(result); // 输出8
1.4 控制结构
- 条件语句:
if
、else if
和else
- 循环语句:
for
和while
void main() {
int num = 5;
if (num > 0) {
print('num is positive');
} else if (num == 0) {
print('num is zero');
} else {
print('num is negative');
}
for (int i = 0; i < 5; i++) {
print(i);
}
}
1.5 类与对象
在Dart中,可以定义类来创建对象。
class Person {
String name;
int age;
Person(this.name, this.age);
void display() {
print('Name: $name, Age: $age');
}
}
void main() {
Person person = Person('John', 25);
person.display();
}
2. Flutter Widget简介
2.1 Widget组成
在Flutter中,每一个UI组件都是一个Widget。Widget是构建Flutter应用的基础。
2.2 常见Widget
- Text:显示文本。
- Image:显示图片。
- Button:显示按钮。
- ListView:显示列表。
- GridView:显示网格。
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Hello, World!'),
Image.network('https://example.com/image.jpg'),
ElevatedButton(
onPressed: () {},
child: Text('Click Me'),
),
ListView(
children: <Widget>[
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
],
),
GridView.count(
crossAxisCount: 3,
children: <Widget>[
Container(color: Colors.blue),
Container(color: Colors.green),
Container(color: Colors.red),
],
),
],
),
),
),
);
}
}
3. 布局与样式
3.1 布局方式
- Stack:堆叠布局。
- Column:垂直排列布局。
- Row:水平排列布局。
- Container:定义大小和位置。
3.2 样式应用
- Text样式:通过
TextStyle
设置文本样式,如字体大小、颜色等。 - Container样式:通过
BoxDecoration
设置背景颜色、边框等。 - SizedBox:用于定义固定大小的控件。
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
'Hello, World!',
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
);
}
}
常用Widget使用方法
1. Text和Image Widget
Text Widget
Text Widget用于显示文本。
Text(
'Hello, World!',
style: TextStyle(
fontSize: 20,
color: Colors.blue,
),
)
Image Widget
Image Widget用于显示图片。
Image.network('https://example.com/image.jpg')
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Hello, World!',
style: TextStyle(
fontSize: 20,
color: Colors.blue,
),
),
Image.network('https://example.com/image.jpg'),
],
),
),
),
);
}
}
2. Button和Input Widget
Button Widget
Button Widget是用户交互的基础。
ElevatedButton(
onPressed: () {
print('Button pressed!');
},
child: Text('Click Me'),
)
Input Widget
Input Widget用于获取用户输入。
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
),
onChanged: (value) {
print('Name: $value');
},
)
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
print('Button pressed!');
},
child: Text('Click Me'),
),
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
),
onChanged: (value) {
print('Name: $value');
},
),
],
),
),
),
);
}
}
3. ListView和GridView
ListView
ListView用于显示一个垂直滚动的列表。
ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
)
GridView
GridView用于显示一个网格。
GridView.builder(
itemCount: 10,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return Container(
color: Colors.blue,
child: Center(
child: Text('Item $index'),
),
);
},
)
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
),
Expanded(
child: GridView.builder(
itemCount: 10,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return Container(
color: Colors.blue,
child: Center(
child: Text('Item $index'),
),
);
},
),
),
],
),
),
);
}
}
响应式编程与事件处理
1. 事件监听
事件类型
- 按钮点击事件
- 文本输入事件
- 屏幕旋转事件
事件监听方法
使用onPressed
属性监听按钮点击事件。
ElevatedButton(
onPressed: () {
print('Button pressed!');
},
child: Text('Click Me'),
)
使用onChanged
属性监听文本输入事件。
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
),
onChanged: (value) {
print('Name: $value');
},
)
使用onOrientationChanged
属性监听屏幕旋转事件。
FutureBuilder(
future: Future.value(),
builder: (context, snapshot) {
return OrientationBuilder(
builder: (context, orientation) {
if (orientation.orientation == DeviceOrientation.portraitUp) {
return Text('Portrait mode');
} else if (orientation.orientation == DeviceOrientation.landscapeLeft) {
return Text('Landscape mode');
}
return Text('Unknown mode');
},
);
},
)
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String name = '';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
print('Button pressed!');
},
child: Text('Click Me'),
),
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
),
onChanged: (value) {
setState(() {
name = value;
});
},
),
Text(name),
],
),
),
),
);
}
}
2. 状态管理基础
状态管理方式
- StatefulWidget
- Provider
StatefulWidget
使用StatefulWidget
管理组件状态。
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
void incrementCount() {
setState(() {
count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text('Count: $count'),
ElevatedButton(
onPressed: incrementCount,
child: Text('Increment'),
),
],
);
}
}
Provider
使用Provider
管理全局状态。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CounterModel()),
],
child: MyApp(),
),
);
}
class CounterModel with ChangeNotifier {
int count = 0;
void incrementCount() {
count++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count: ${Provider.of<CounterModel>(context).count}'),
ElevatedButton(
onPressed: () {
Provider.of<CounterModel>(context, listen: false).incrementCount();
},
child: Text('Increment'),
),
],
),
),
),
);
}
}
示例代码:
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CounterModel()),
],
child: MyApp(),
),
);
}
class CounterModel with ChangeNotifier {
int count = 0;
void incrementCount() {
count++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count: ${Provider.of<CounterModel>(context).count}'),
ElevatedButton(
onPressed: () {
Provider.of<CounterModel>(context, listen: false).incrementCount();
},
child: Text('Increment'),
),
],
),
),
),
);
}
}
3. Navigator和路由管理
Navigator
Navigator用于管理应用的页面导航。
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
)
路由管理
使用MaterialPageRoute
和CupertinoPageRoute
来创建不同的页面。
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Text('Go to Second Page'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}
示例代码:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute: '/',
routes: {
'/': (context) => FirstPage(),
'/second': (context) => SecondPage(),
},
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/second');
},
child: Text('Go to Second Page'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}
Flutter项目的构建与发布
1. 创建Flutter项目
创建Flutter项目
使用命令行工具创建一个Flutter项目。
flutter create my_flutter_app
cd my_flutter_app
添加依赖
在pubspec.yaml
文件中添加依赖。
dependencies:
flutter:
sdk: flutter
provider: ^4.3.3 # 示例依赖
运行项目
使用命令行工具运行项目。
flutter run
示例代码:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CounterModel()),
],
child: MyApp(),
),
);
}
class CounterModel with ChangeNotifier {
int count = 0;
void incrementCount() {
count++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count: ${Provider.of<CounterModel>(context).count}'),
ElevatedButton(
onPressed: () {
Provider.of<CounterModel>(context, listen: false).incrementCount();
},
child: Text('Increment'),
),
],
),
),
),
);
}
}
2. 调试与测试
调试工具
使用flutter run --debug
命令进行调试。
flutter run --debug
单元测试
在test
目录下编写单元测试代码。
import 'package:flutter_test/flutter_test.dart';
import 'package:my_flutter_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0.
expect(find.text('Count: 0'), findsOneWidget);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.text('+'));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('Count: 1'), findsOneWidget);
});
}
示例代码:
import 'package:flutter_test/flutter_test.dart';
import 'package:my_flutter_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0.
expect(find.text('Count: 0'), findsOneWidget);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.text('Increment'));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('Count: 1'), findsOneWidget);
});
}
3. 发布应用到各大平台
准备发布
在发布之前,需要完成以下操作:
- 清理项目
- 生成签名文件
- 更新
pubspec.yaml
文件中的版本号
发布流程
-
清理项目
使用以下命令清理项目:
flutter clean
-
生成签名文件
生成Android和iOS的签名文件。
- Android:在Android Studio中生成
keystore
文件。 - iOS:在Xcode中生成
App ID
和Provisioning Profile
。
- Android:在Android Studio中生成
-
更新版本号
修改
pubspec.yaml
文件中的版本号。version: 1.0.0+1
-
发布到Google Play
将应用打包为
.aab
文件并上传到Google Play。flutter build appbundle --release
-
发布到App Store
将应用打包为
.ipa
文件并上传到App Store Connect。flutter build ios --release
示例代码:
flutter clean
# 生成Android签名文件
# 在Android Studio中生成`keystore`文件
# 源自命令:
keytool -genkey -v -keystore my-release-key.jks -keyalias my-key-alias -keyalg RSA -storetype JKS -storepass my-store-password -keypass my-key-password -validity 10000 -destdir ~/.android -destfile my-release-key.jks
# 生成iOS签名文件
# 在Xcode中生成`App ID`和`Provisioning Profile`
# 更新版本号
version: 1.0.0+1
# 打包并发布
flutter build appbundle --release
flutter build ios --release
实战案例:制作个人简历App
1. 项目需求分析
需求描述
- 首页:展示个人信息,如姓名、职位、联系方式等。
- 工作经历:展示工作经历,如公司名称、职位、时间等。
- 教育背景:展示教育背景,如学校名称、专业、时间等。
- 技能特长:展示技能特长,如编程语言、工具等。
- 项目经验:展示项目经验,如项目名称、简介、时间等。
项目结构
lib/
├── main.dart
├── models/
│ ├── resume.dart
├── pages/
│ ├── home_page.dart
│ ├── work_experience_page.dart
│ ├── education_background_page.dart
│ ├── skills_page.dart
│ └── projects_page.dart
├── service/
│ └── resume_service.dart
└── utils/
└── constants.dart
2. 页面设计与实现
首页实现
在home_page.dart
文件中实现首页。
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
import 'package:my_resume/utils/constants.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('个人简历'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${Resume.instance.name}',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${Resume.instance.position}',
style: TextStyle(fontSize: 18, color: kTextColorSecondary),
),
SizedBox(height: 20),
Text(
'联系方式',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'电话: ${Resume.instance.phone}',
style: TextStyle(fontSize: 14),
),
Text(
'邮箱: ${Resume.instance.email}',
style: TextStyle(fontSize: 14),
),
Text(
'地址: ${Resume.instance.address}',
style: TextStyle(fontSize: 14),
),
],
),
),
);
}
}
示例代码:
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
import 'package:my_resume/utils/constants.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('个人简历'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${Resume.instance.name}',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${Resume.instance.position}',
style: TextStyle(fontSize: 18, color: kTextColorSecondary),
),
SizedBox(height: 20),
Text(
'联系方式',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'电话: ${Resume.instance.phone}',
style: TextStyle(fontSize: 14),
),
Text(
'邮箱: ${Resume.instance.email}',
style: TextStyle(fontSize: 14),
),
Text(
'地址: ${Resume.instance.address}',
style: TextStyle(fontSize: 14),
),
],
),
),
);
}
}
工作经历实现
在work_experience_page.dart
文件中实现工作经历页面。
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class WorkExperiencePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('工作经历'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: Resume.instance.workExperiences.length,
itemBuilder: (context, index) {
final workExperience = Resume.instance.workExperiences[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${workExperience.company}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${workExperience.position}',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 10),
Text(
'${workExperience.startDate} - ${workExperience.endDate}',
style: TextStyle(fontSize: 14),
),
Divider(),
],
);
},
),
),
);
}
}
示例代码:
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class WorkExperiencePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('工作经历'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: Resume.instance.workExperiences.length,
itemBuilder: (context, index) {
final workExperience = Resume.instance.workExperiences[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${workExperience.company}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${workExperience.position}',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 10),
Text(
'${workExperience.startDate} - ${workExperience.endDate}',
style: TextStyle(fontSize: 14),
),
Divider(),
],
);
},
),
),
);
}
}
教育背景实现
在education_background_page.dart
文件中实现教育背景页面。
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class EducationBackgroundPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('教育背景'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: Resume.instance.educationBackground.length,
itemBuilder: (context, index) {
final education = Resume.instance.educationBackground[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${education.school}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${education.major}',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 10),
Text(
'${education.startDate} - ${education.endDate}',
style: TextStyle(fontSize: 14),
),
Divider(),
],
);
},
),
),
);
}
}
示例代码:
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class EducationBackgroundPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('教育背景'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: Resume.instance.educationBackground.length,
itemBuilder: (context, index) {
final education = Resume.instance.educationBackground[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${education.school}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${education.major}',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 10),
Text(
'${education.startDate} - ${education.endDate}',
style: TextStyle(fontSize: 14),
),
Divider(),
],
);
},
),
),
);
}
}
技能特长实现
在skills_page.dart
文件中实现技能特长页面。
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class SkillsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('技能特长'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'编程语言',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
...Resume.instance.programmingLanguages.map((language) {
return Text(
language,
style: TextStyle(fontSize: 14),
);
}),
SizedBox(height: 20),
Text(
'工具',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
...Resume.instance.tools.map((tool) {
return Text(
tool,
style: TextStyle(fontSize: 14),
);
}),
],
),
),
);
}
}
示例代码:
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class SkillsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('技能特长'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'编程语言',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
...Resume.instance.programmingLanguages.map((language) {
return Text(
language,
style: TextStyle(fontSize: 14),
);
}),
SizedBox(height: 20),
Text(
'工具',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
...Resume.instance.tools.map((tool) {
return Text(
tool,
style: TextStyle(fontSize: 14),
);
}),
],
),
),
);
}
}
项目经验实现
在projects_page.dart
文件中实现项目经验页面。
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class ProjectsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('项目经验'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: Resume.instance.projects.length,
itemBuilder: (context, index) {
final project = Resume.instance.projects[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${project.name}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${project.description}',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 10),
Text(
'${project.startDate} - ${project.endDate}',
style: TextStyle(fontSize: 14),
),
Divider(),
],
);
},
),
),
);
}
}
示例代码:
import 'package:flutter/material.dart';
import 'package:my_resume/models/resume.dart';
class ProjectsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('项目经验'),
),
body: Padding(
padding: EdgeInsets.all(16),
child: ListView.builder(
itemCount: Resume.instance.projects.length,
itemBuilder: (context, index) {
final project = Resume.instance.projects[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${project.name}',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text(
'${project.description}',
style: TextStyle(fontSize: 14),
),
SizedBox(height: 10),
Text(
'${project.startDate} - ${project.endDate}',
style: TextStyle(fontSize: 14),
),
Divider(),
],
);
},
),
),
);
}
}
3. 功能实现与优化
功能实现
- 导航:使用
Navigator
实现页面之间的导航。 - 数据持久化:使用本地存储或远程服务保存简历数据。
- 样式优化:使用
Theme
和ThemeData
优化整体样式。
数据持久化
可以使用SharedPreferences
保存简历数据。
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:my_resume/models/resume.dart';
class ResumeService {
Future<void> saveResume(Resume resume) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString('resume', json.encode(resume.toJson()));
}
Future<Resume> loadResume() async {
final prefs = await SharedPreferences.getInstance();
final resumeJson = prefs.getString('resume');
if (resumeJson != null) {
return Resume.fromJson(json.decode(resumeJson));
}
return Resume();
}
}
示例代码:
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:my_resume/models/resume.dart';
class ResumeService {
Future<void> saveResume(Resume resume) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString('resume', json.encode(resume.toJson()));
}
Future<Resume> loadResume() async {
final prefs = await SharedPreferences.getInstance();
final resumeJson = prefs.getString('resume');
if (resumeJson != null) {
return Resume.fromJson(json.decode(resumeJson));
}
return Resume();
}
}
样式优化
使用Theme
和ThemeData
优化整体样式。
import 'package:flutter/material.dart';
import 'package:my_resume/pages/home_page.dart';
import 'package:my_resume/pages/work_experience_page.dart';
import 'package:my_resume/pages/education_background_page.dart';
import 'package:my_resume/pages/skills_page.dart';
import 'package:my_resume/pages/projects_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '个人简历',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
scaffoldBackgroundColor: Colors.grey[200],
textTheme: TextTheme(
bodyText1: TextStyle(fontSize: 16),
bodyText2: TextStyle(fontSize: 14),
),
),
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/work_experience': (context) => WorkExperiencePage(),
'/education_background': (context) => EducationBackgroundPage(),
'/skills': (context) => SkillsPage(),
'/projects': (context) => ProjectsPage(),
},
);
}
}
示例代码:
import 'package:flutter/material.dart';
import 'package:my_resume/pages/home_page.dart';
import 'package:my_resume/pages/work_experience_page.dart';
import 'package:my_resume/pages/education_background_page.dart';
import 'package:my_resume/pages/skills_page.dart';
import 'package:my_resume/pages/projects_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '个人简历',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
scaffoldBackgroundColor: Colors.grey[200],
textTheme: TextTheme(
bodyText1: TextStyle(fontSize: 16),
bodyText2: TextStyle(fontSize: 14),
),
),
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/work_experience': (context) => WorkExperiencePage(),
'/education_background': (context) => EducationBackgroundPage(),
'/skills': (context) => SkillsPage(),
'/projects': (context) => ProjectsPage(),
},
);
}
}
总结
通过以上步骤,我们实现了一个简单的个人简历App。这个App不仅能够展示个人信息,还能够展示工作经历、教育背景、技能特长和项目经验,为求职者提供了一种专业的展示方式。在实际应用中,还可以进一步优化和扩展功能,以满足更多的需求。
共同学习,写下你的评论
评论加载中...
作者其他优质文章