Flutter學(xué)習(xí)總結(jié)之四 常見Widget及頁面跳轉(zhuǎn)

一.常見布局方式

  • Row,是水平方向的線性布局(linearlayout)

  • Column,是垂直方向的線性布局(linearlayout)

  • Stack,可以理解成為相對(duì)布局。

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          child: new Column(
            children: <Widget>[
              new Text('Text 1'),
              new Text('Text 2'),
              new Text('Text 3')
            ],),),),);}
}

二.事件

在 Flutter 中,有兩種方法來添加點(diǎn)擊監(jiān)聽者:
1、如果 widget 本身支持事件監(jiān)測(cè),直接傳遞給它一個(gè)函數(shù),并在這個(gè)函數(shù)里實(shí)現(xiàn)響應(yīng)方法。例如,RaisedButton、IconButton、OutlineButton、Checkbox、SnackBar、Switch等。

body:Center(
  child: OutlineButton(
    child: Text('點(diǎn)擊我'),
     onPressed: (){
          Fluttertoast.showToast(
                    msg: '你點(diǎn)擊了FlatButton',
            toastLength: Toast.LENGTH_SHORT,
                gravity: ToastGravity.CENTER,
        timeInSecForIos: 1,
     );
  }),
),

2、如果 widget 本身不支持事件監(jiān)測(cè),則在外面包裹一個(gè) GestureDetector,并給它的 onTap 屬性傳遞一個(gè)函數(shù):

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GestureDetector(
          child: FlutterLogo(
            size: 200.0,
          ),
          onTap: () {
            print("tap");
          },
        ),
      ),
    );
  }
}

3、widget 上的其他手勢(shì)

屬性 取值意義
onTapDwon 當(dāng)按下屏幕時(shí)觸發(fā)
onTap 當(dāng)與屏幕短暫地觸碰時(shí)觸發(fā),最常用
onTapUp 當(dāng)用戶停止觸碰屏幕時(shí)觸發(fā)
onTapCancel 當(dāng)用戶觸摸屏幕,但沒有完成Tap事件時(shí)觸發(fā)
onDoubleTap 快速雙擊屏幕時(shí)觸發(fā)
onLongPress 當(dāng)長(zhǎng)按屏幕時(shí)觸發(fā)(與屏幕接觸事件必須超過500ms)
onPanUpdate 當(dāng)在屏幕上移動(dòng)時(shí)觸發(fā)
onVerticalDragDown 當(dāng)手指觸碰屏幕且準(zhǔn)備往屏幕垂直方向移動(dòng)時(shí)觸發(fā)
onVerticalDragStart 當(dāng)手指觸碰屏幕且開始往屏幕垂直方向移動(dòng)時(shí)觸發(fā)
onVerticalDragUpdate 當(dāng)手指觸碰屏幕且開始往屏幕垂直方向移動(dòng)并發(fā)生位移時(shí)觸發(fā)
onVerticalDragEnd 當(dāng)用戶完成垂直方向觸摸屏幕時(shí)觸發(fā)
onVerticalDragCancel 當(dāng)用戶中斷了onVerticalDragDown時(shí)觸發(fā)
onHorizontalDragDown 當(dāng)手指觸摸屏幕且準(zhǔn)備往屏幕水平方向移動(dòng)時(shí)觸發(fā)
onHorizontalDragStart 當(dāng)手指觸摸屏幕且開始往屏幕水平方向移動(dòng)時(shí)觸發(fā)
onHorizontalDragUpdate 當(dāng)手指觸摸屏幕且開始往屏幕水平方向移動(dòng)并發(fā)生位移時(shí)觸發(fā)
onHorizontalDragEnd 當(dāng)用戶完成水平方向觸摸屏幕時(shí)觸發(fā)
onHorizontalDragCancel 當(dāng)用戶中斷了onHorizontalDragDown時(shí)觸發(fā)
onPanDown 當(dāng)用戶觸摸屏幕時(shí)觸發(fā)
onPanStart 當(dāng)用戶觸摸屏幕并開始移動(dòng)時(shí)觸發(fā)
onPanUpdate 當(dāng)用戶觸摸屏幕并產(chǎn)生移動(dòng)時(shí)觸發(fā)
onPanEnd 當(dāng)用戶完成觸摸屏幕時(shí)觸發(fā)
onScaleStart 當(dāng)用戶觸摸屏幕并開始縮放時(shí)觸發(fā)
onScaleUpdate 當(dāng)用戶觸摸屏幕并產(chǎn)生縮放時(shí)觸發(fā)
onScaleEnd 當(dāng)用戶完成縮放時(shí)觸發(fā)

三.跳轉(zhuǎn)頁面(路由和導(dǎo)航)

Flutter 中萬物皆 Widget,頁面自然也是一個(gè) Widget。只不過是一個(gè)全屏的 Widget。在flutter中三種頁面跳轉(zhuǎn)方式:無名路由跳轉(zhuǎn)(一種動(dòng)態(tài)構(gòu)建路由的方式)、命名路由跳轉(zhuǎn)(一種提前命名路由的方式)

1.無名路由跳轉(zhuǎn)

直接使用使用 Navigator 跳轉(zhuǎn)頁面,在 Flutter 中,使用 Navigator 來進(jìn)行頁面跳轉(zhuǎn)。一個(gè)簡(jiǎn)單的跳轉(zhuǎn)頁面的例子:

          Navigator.push(
            context,
            MaterialPageRoute(
            // 目標(biāo)頁面,即一個(gè) Widget
              builder: (context) => PageA(),
            ),
          );

或者

          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (context) => PageA(),
            ),
          );

關(guān)閉A頁面返回到上一個(gè)頁面

Navigator.pop(context);

或者

 Navigator.of(context).pop();

2.命名路由跳轉(zhuǎn)

命名路由路由存在的意義在于可以讓我們更方便的導(dǎo)航到想要到達(dá)的頁面,便于管理和維護(hù)。

void main() => runApp(MyApp());//單行函數(shù)調(diào)用寫法
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "My App Title",
      theme: ThemeData(primaryColor: Colors.green),
      //home: RandomWord(),//初始路由頁面一
      initialRoute: "one_route",//初始路由頁面二
      routes: {
        //路由注冊(cè)表
        "second_page": (BuildContext context) {
          return NextPage(ModalRoute.of(context).settings.arguments);
        },
        "one_route": (BuildContext context) => RandomWord(),
      },
    );
  }
}

可以通過剛剛注冊(cè)的頁面名稱來跳轉(zhuǎn)一個(gè)頁面:

Navigator.pushNamed(context, 'one_route');// one_route表示頁面別名

3.接收參數(shù)

傳遞的方式有兩種:

  • 在構(gòu)造方法中傳遞數(shù)據(jù)
  • 在Route中傳遞數(shù)據(jù)給下一個(gè)頁面

(1)構(gòu)造方法中傳遞數(shù)據(jù)
需要在接收數(shù)據(jù)的頁面事先定義好構(gòu)造方法,構(gòu)造方法中是要接收的參數(shù)。例如:我們?cè)赑ageB中定義一個(gè)構(gòu)造方法,構(gòu)造方法中可以定義我們要接收的數(shù)據(jù):

import 'package:flutter/material.dart';

class PageB extends StatelessWidget {
  String data;

  PageB({this.data});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("B頁面"),
        leading: InkWell(
          onTap: () {
            Navigator.pop(pageContext);
          },
          child: Icon(
            Icons.arrow_back,
          ),
        ),
      ),
      body: Center(
        child: Text(data),
      ),
    );
  }
}

跳轉(zhuǎn)頁面時(shí)給PageB傳遞數(shù)據(jù):

    Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => PageB(
                    data: "要傳遞的數(shù)據(jù)",
                  ),
            ),
          );

(2)將參數(shù)傳遞給指定路由
方式一不是太靈活。Flutter也提供了類似于Android那種通過Intent傳值的方式,在Flutter中我們可以把要傳遞的參數(shù)放到Navigator中,然后傳遞給指定的路由,在接收的頁面提取出需要的參數(shù)即可,這種方式相比方式一更加靈活一些。通過路由進(jìn)行導(dǎo)航時(shí)用到了Navigator.pushNamed(context, pageA);這個(gè)方法,實(shí)際上這個(gè)方法還有第三個(gè)參數(shù),
1.首先我們要先定義好要傳遞的數(shù)據(jù)
例如:
我們先定義一個(gè)實(shí)體類:

class People {
  String name;
  int age;
  People(this.name, this.age);
}

2.傳遞參數(shù)
將參數(shù)數(shù)據(jù)傳遞給PageB,可以有如下四種傳參方式,效果都一樣

          Navigator.pushNamed(
            context,
            pageB,
            arguments: People("yzq", 25),//要傳遞的數(shù)據(jù)
          );

或者

Navigator.of(context).pushNamed(pageB, arguments: People("yzq", 25));

或者·

Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => PageB(),
              settings: RouteSettings(
                arguments: People("yuzhiqiang", 26),
              ),
            ),
          );

或者

          Navigator.of(context).push(
            MaterialPageRoute(
                builder: (context) => PageB(),
                settings: RouteSettings(
                    arguments: People("yuzhiqiang", 26),
                )
            ),
          );

3.接收參數(shù)

在PageB接收數(shù)據(jù),接收數(shù)據(jù)要通過 ModalRoute.of 方法。此方法返回帶有參數(shù)的當(dāng)前路由。

import 'package:flutter/material.dart';
import 'package:flutter_router/people.dart';

class PageB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /*獲取傳遞過來的參數(shù)*/
    People _people = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      appBar: AppBar(
        title: Text("B頁面"),
        leading: InkWell(
          onTap: () {
            Navigator.pop(context);
          },
          child: Icon(
            Icons.arrow_back,
          ),
        ),
      ),
      body: Center(
        child: Text("姓名:${_people.name},年齡:${_people.age}"),
      ),
    );
  }
}

更多信息參考 Navigator API

Flutter布局方式總
Flutter 初嘗試:入門教程
GSY Flutter 系列專欄
flutter中文網(wǎng)
Flutter入門進(jìn)階之旅

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容