应用程序一般包含多个界面,在Flutter中把每一个页面成为路由(Route),这些路由的跳转由导航器(Navigator)管理。导航器管理着路由对象的堆栈,并提供管理堆栈的方法,如Navigator.push和Navigator.pop。通过路由对象的进出栈使用户从一个页面跳转到另一个页面。
Flutter中的存储按照数据量的大小和复杂度可以分为两类,简单的数据使用shared_preferences,对于比较大的数据量,使用数据库SQLite。
一、路由导航
路由是应用程序页面抽象出来的概念,一个页面对应一个路由。flutter中一个路由对应一个Widget,路由是由Navigator管理的。Navigator管理路由对象的堆栈,并提供管理堆栈的方法,Navigator的push方法是将一个新得路由添加到堆栈中,即打开一个页面,
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return HeroDetailDemo();
}));
Navigator的push方法的参数是一个MaterialPageRoute,MaterialPageRoute继承PageRoute,是Material组件提供的。MaterialPageRoute实现了在不同平台页面切换时不同的动画效果。跳转页面加入参数效果:
onPressed: () async {
var data = await Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return TwoPage("我来自第一个界面的数据");
}));
``
第二个界面传值给第一个界面:
```c
Navigator.of(context).pop('来自第二个界面的参数');
pop方法是将一个路由出栈,即界面返回上一个页面,
//1、第一个界面跳转到第二个界面;
//2、第一个界面传参数到第二个界面;
//3、第二个界面向第一个界面返回值;
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: OnePage(),
);
}
}
class OnePage extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return _OnePage();
throw UnimplementedError();
}
}
class _OnePage extends State<OnePage>{
String result = "你好";
reflesh(String data) {
setState(() {
result = data;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("OnePage"),
centerTitle: true,
),
body: Center(
child:Column(
children: <Widget>[
RaisedButton(
child: Text('点击跳转到第二个界面'),
onPressed: () async {
var data = await Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return TwoPage("我来自第一个界面的数据");
}));
reflesh(data);
},
),
Text(result),
],
),
),
);
throw UnimplementedError();
}
}
class TwoPage extends StatelessWidget{
String data;
TwoPage(String data) {
this.data = data;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TwoPage"),
centerTitle: true,
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text('点击返回第一个界面'),
onPressed: () {
Navigator.of(context).pop('来自第二个界面的参数');
},
),
Text(data),
],
)
),
);
throw UnimplementedError();
}
}
二、命名路由
命名路由就是给路由起一个名字,可以直接通过名字打开新得路由,这种方式更加方便管理路由,建议再实际项目中使用命名路由的方式,使用命名路由首先需要创建一个路由表,创建方式如下:
//创建路由表
class Routes{
static const String onePage = 'one_page';
static const String twoPage = 'two_page';
static Map<String,WidgetBuilder> routes = {
onePage:(context) =>OnePage(),
twoPage:(context) =>TwoPage(),
// twoPage:(context) =>TwoPage(ModalRoute.of(context).settings.arguments),
};
}
注册路由表
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routes: Routes.routes,
home: OnePage(),
);
}
}
//使用路由方法打开新界面
var result = await Navigator.of(context).pushNamed(Routes.twoPage);
命名路由传递参数及接收参数
//传递参数
var result = await Navigator.of(context).pushNamed(Routes.twoPage,arguments: {
'name':'flutter'
//获取参数
Map data = ModalRoute.of(context).settings.arguments;
三、shared_preferences存储数据
使用shared_preferences再pubspec.yaml中添加依赖shared_preferences: ^0.5.6,用flutter packages get获取
增加/修改数据:
var prefs = await SharedPreferences.getInstance();
prefs.setString('name', 'lily');
获取数据:
var prefs = await SharedPreferences.getInstance();
prefs.getString('name');
删除数据
var prefs = await SharedPreferences.getInstance();
prefs.remove('name');
四、SQLite存储数据
1、使用SQLite数据库需要添加sqfile依赖
sqflite: ^1.1.0
2、定义一个User类,对应数据库的数据结构,
class User {
User(this.id,this.name,this.age);
final int id;
final String name;
final int age;
toMap() {
return {'id':this.id,'name':this.name,'age':this.age};
}
}
3、打开数据库连接
Future<Database> _db = openDatabase('user.db',version: 1,onCreate: (Database db,int version) {
//创建表,分3列,分别为id,name,age,id为主键
db.execute('CREATE TABLE User(id INTEGER PRIMARY KEY,name TEXT, age INTEGER)');
});
4、向User表中插入数据
Insert(String _table,User user) async {
var db = await _db;
var result = await db.insert(_table, user.toMap());
Scaffold.of(context).showSnackBar(SnackBar(content: Text('保存成功'),));
}
5、查询User中所有数据
var db = await _db;
var list = await db.query(_table);
根据id查询匹配的数据
var list = await db.query(_table,where: 'id=?',whereArgs: [id]);
6、根据id更新User表中匹配的数据
var result = await db.update(_table, user.toMap(),where: 'id=?',whereArgs: [user.id]);
7、根据id删除User表中匹配的数据,
var result = await db.delete(_table, where: 'id=?',whereArgs: [id]);
//數據庫操作,可以運行
mport 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sqflite/sqflite.dart';
class User {
User(this.id,this.name,this.age);
final int id;
final String name;
final int age;
toMap() {
return {'id':this.id,'name':this.name,'age':this.age};
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SQLTest(),
);
}
}
class SQLTest extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return _SQLTest();
throw UnimplementedError();
}
}
class _SQLTest extends State<SQLTest>{
String _id = "id";
String _name = "name";
String _age = "age";
List<User> _list = new List<User>();
final String _table = 'User';
Future<Database> _db = openDatabase('user.db',version: 1,onCreate: (Database db,int version) {
db.execute('CREATE TABLE User (id INTEGER PRIMARY KEY,name TEXT, age INTEGER)');
});
//保存數據
insert(User user) async {
var db = await _db;
var result = await db.insert(_table, user.toMap());
Scaffold.of(context).showSnackBar(SnackBar(content: Text('保存成功,$result'),));
}
//查詢全部數據
query() async {
var db = await _db;
var list = await db.query(_table);
_list.clear();
list.forEach((map) {
_list.add(User(map['id'],map['name'],map['age']));
});
setState(() {
});
}
//根據id查詢全部數據
queryById(int id) async {
var db = await _db;
var list = await db.query(_table,where: 'id=?',whereArgs: [id]);
_list.clear();
list.forEach((map) {
_list.add(User(map['id'],map['name'],map['age']));
});
setState(() {
});
}
//更新
update(User user) async {
var db = await _db;
var result = await db.update(_table, user.toMap(),where: 'id=?',whereArgs: [user.id]);
Scaffold.of(context).showSnackBar(SnackBar(content: Text('更新成功,$result')));
}
//刪除數據
deleteById(int id) async {
var db = await _db;
var result = await db.delete(_table,where: 'id=?',whereArgs: [id]);
Scaffold.of(context).showSnackBar(SnackBar(content: Text('刪除成功,$result'),));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SQLTest'),
),
body: Column(
children: <Widget>[
Form(
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'id'),
onChanged: (value) {
setState(() {
_id = value;
});
},
),
TextField(
decoration: InputDecoration(hintText: 'name'),
onChanged: (value) {
setState(() {
_name = value;
});
},
),
TextField(
decoration: InputDecoration(hintText: 'age'),
onChanged: (value) {
setState(() {
_age = value;
});
},
),
],
),
),
Wrap(
children: <Widget>[
RaisedButton(
child: Text('提交'),
onPressed: () {
var user = User(int.parse(_id),_name,int.parse(_age));
insert(user);
},
),
RaisedButton(
child: Text('查询全部'),
onPressed: () {
query();
},
),
RaisedButton(
child: Text('查询'),
onPressed: () {
int id = int.parse(_id);
queryById(id);
},
),
RaisedButton(
child: Text('更新'),
onPressed: () {
update(User(int.parse(_id),_name,int.parse(_age)));
},
),
RaisedButton(
child: Text('删除'),
onPressed: () {
int id = int.parse(_id);
deleteById(id);
},
),
],
),
Flexible(
child: ListView.builder(
itemBuilder: (context,index) {
return Container(
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text('id${_list[index].id}'),
Text('name${_list[index].name}'),
Text('age${_list[index].age}'),
],
),
);
},
itemCount: _list.length,
),
),
],
),
);
throw UnimplementedError();
}
}