flutter移動開發中的頁面跳轉和傳值

在安卓原生開發中,頁面跳轉能夠用Intent類來具體實現:javascript

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

startActivity(intent);

而在安卓開發中,頁面傳值有多種方法,常見的能夠用intent、Bundle、自定義類、靜態變量等等來傳值,甚至能夠用SharedPreferences來保存鍵值對等數據。前端

在Flutter中,頁面跳轉和傳值也具備相應的方法,只不過方式更加符合目前的技術潮流標準。vue

具體的實現的是:final Map<String, WidgetBuilder> routes; java

根據Flutter的文檔,routes的靈感來源於reactjs,routes能夠翻譯爲路由,能夠看到這種routes的思路在目前的設計中彼此借鑑,routes的思路不只在前端流行,好比在vue、reactjs、Angular中用到,並且在後端應用中也很是成熟。react

一:在flutter中實現頁面的跳轉的代碼:android

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('返回'),
        ),
      ),
    );
  }
}

上面的代碼中,能夠看到web

Navigator.push(
              context,
              new MaterialPageRoute(builder: (context) => new SecondScreen()),
            );

MaterialPageRoute裏面已經實現了具體的方法,此處的Material中文翻譯爲一種材質設計風格,Material Design風格爲谷歌設計,它是一種界面設計標準,爲平板、手機、web等提供一致、普遍的外觀,目前在國外是一種很是受歡迎的UI設計標準。windows

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設計的方式你們比較容易接受,可是時代在改變,技術在更新。

相關文章
相關標籤/搜索