在安卓原生开发中,页面跳转可以用Intent类来具体实现:
Intent intent =new Intent(MainActivity.this,second.class);
startActivity(intent);
而在安卓开发中,页面传值有多种方法,常见的可以用intent、Bundle、自定义类、静态变量等等来传值,甚至可以用SharedPreferences来保存键值对等数据。
在Flutter中,页面跳转和传值也具有相应的方法,只不过方式更加符合目前的技术潮流标准。
具体的实现的是:final Map routes;
根据Flutter的文档,routes的灵感来源于reactjs,routes可以翻译为路由,可以看到这种routes的思路在目前的设计中彼此借鉴,routes的思路不仅在前端流行,比如在vue、reactjs、Angular中用到,而且在后端应用中也非常成熟。
一:在flutter中实现页面的跳转的代码:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: '页面跳转',
home: new FirstScreen(),
));
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('第一个页面'),
backgroundColor: Colors.red,
),
body: new Center(
child: new RaisedButton(
child: new Text('跳转'),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondScreen()),
);
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('第二个页面'),
backgroundColor: Colors.brown,
),
body: new Center(
child: new RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: new Text('返回'),
),
),
);
}
}
上面的代码中,可以看到
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondScreen()),
);
MaterialPageRoute里面已经实现了具体的方法,此处的Material中文翻译为一种材质设计风格,Material Design风格为谷歌设计,它是一种界面设计标准,为平板、手机、web等提供一致、广泛的外观,目前在国外是一种非常受欢迎的UI设计标准。
Navigator.push: Navigator具体翻译为导航、跳转。为了显得简单易懂,这里不用指针解释push, 我这里用另外一种简单的方法来解释,在javascript中用push() 方法可向数组的末尾添加一个或多个元素,这就简单易懂了,就是追加一个页面来显示(SecondScreen页面)。
context:代表上下文,也就是类似windows中的句柄,指的是当前的这个页面窗口。
Navigator.pop(context);
Navigator.pop(context):pop在javascript中用于删除数组的最末一个元素,这就明白了,就是删除当前页面返回到Navigator中的前一个页面。
二:flutter实现传值的方法。
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('第二个页面'),
backgroundColor: Colors.brown,
),
body: new Center(
child: new RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: new Text('返回'),
),
),
);
}
}
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
void main() {
runApp(new MaterialApp(
title: '传递数据',
home: new TodosScreen(
todos: new List.generate(
20,
(i) => new Todo(
'我是表头 $i 项',
'我是内容 $i',
),
),
),
));
}
class TodosScreen extends StatelessWidget {
final List todos;
TodosScreen({Key key, @required this.todos}) : super(key: key);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('第一个页面'),
),
body: new ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return new ListTile(
title: new Text(todos[index].title),
subtitle:new Text(todos[index].description) ,
// When a user taps on the ListTile, navigate to the DetailScreen.
// Notice that we're not only creating a new DetailScreen, we're
// also passing the current todo through to it!
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// Declare a field that holds the Todo
final Todo todo;
// In the constructor, require a Todo
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
// Use the Todo to create our UI
return new Scaffold(
appBar: new AppBar(
title: new Text("${todo.title}"),
),
body: new Padding(
padding: new EdgeInsets.all(16.0),
child: new Text('${todo.description}'),
),
);
}
}
可以看到传值过来了,而且代码相当简洁。比起android原生开发来说,显示listview控件数据就少了一堆数据适配器的概念。
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new DetailScreen(todo: todos[index]),
),
);
onTap 代表手指轻触屏幕事件。
这是通过用类来传递值。
DetailScreen({Key key, @required this.todo}) : super(key: key);
可以看到,通过类的初始化,把类传递进来,然后读取类的相关属性来达到传值。
由于篇幅限制,这里不上代码了,flutter传值还可以通过类的静态变量等等多种方法来实现。
三:目前国外比较流行的页面传值是用fluro等第三方插件。
import 'package:flutter/material.dart';
import 'app_route.dart';
import 'package:fluro/fluro.dart';
void main() {
router.define('home/:data', handler: new Handler(
handlerFunc: (BuildContext context, Map params) {
return new Home(params['data'][0]);
}));
runApp(new Login());
}
class Login extends StatefulWidget{
@override
createState() => new LoginState();
}
class LoginState extends State{
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Fluro 例子',
home: new Scaffold(
appBar: new AppBar(
title: new Text("登录"),
),
body: new Builder(builder: (BuildContext context) {
return new Center(child:
new Container(
height: 30.0,
color: Colors.blue,
child:new FlatButton(
child: const Text('传递帐号密码'),
onPressed: () {
var bodyJson = '{"user":1281,"pass":3041}';
router.navigateTo(context, '/home/$bodyJson');
// Perform some action
},
)),
);
}),
/**/
));
}
}
class Home extends StatefulWidget{
final String _result;
Home(this._result);
@override
createState() => new HomeState();
}
class HomeState extends State{
@override
Widget build(BuildContext context) {
return new Center(
child: new Scaffold(
appBar: new AppBar(
title: new Text("个人主页"),
),
body:new Center(child: new Text(widget._result)),
)
);
}
}
'app_route.dart'的代码:
import 'package:fluro/fluro.dart';
Router router = new Router();
可以看到,fluro应用一种比较新潮的方法来传值,更加接近vue、ag、reactjs等传值方式。
var bodyJson = '{"user":1281,"pass":3041}';
router.navigateTo(context, '/home/$bodyJson');
这样一来少写了很多代码,而且在大型的APP开发中,显得更加整洁易懂、易于管理、代码统一等。
综合上述,flutter由于是后起之秀,设计比较大胆,同时借鉴了一些新潮的设计思路。
在android UI开发中,xml布局的方式比较落后了,但是受限于年代,那是10年前的设计,那时候的XML设计的方式大家比较容易接受,但是时代在改变,技术在更新。