flutter移动开发中的页面跳转和传值

原创
2018/04/17 03:34
阅读数 10.8W

在安卓原生开发中,页面跳转可以用Intent类来具体实现:

Intent intent =new Intent(MainActivity.this,second.class);

startActivity(intent);

而在安卓开发中,页面传值有多种方法,常见的可以用intent、Bundle、自定义类、静态变量等等来传值,甚至可以用SharedPreferences来保存键值对等数据。

在Flutter中,页面跳转和传值也具有相应的方法,只不过方式更加符合目前的技术潮流标准。

具体的实现的是:final Map<String, WidgetBuilder> 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<Todo> 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<String, dynamic> params) {
        return new Home(params['data'][0]);
      }));
  runApp(new Login());
}

class Login extends StatefulWidget{
  @override
  createState() => new LoginState();
}

class LoginState extends State<Login>{
  @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<Home>{
  @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设计的方式大家比较容易接受,但是时代在改变,技术在更新。

 

展开阅读全文
打赏
4
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
4
分享
返回顶部
顶部