Flutter学习记录-路由、包、资源管理

接上一章搭建开发环境,这章学习Flutter中,路由、包、资源的管理。

1、路由管理

Flutter中的路由名为route,可以理解为Android中的activity。路由管理也就是指route之间的跳转、传值、回传数据。主要由Navigator控制,Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator通过一个栈来管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由。Navigator提供了一系列方法来管理路由栈,在此我们只介绍其最常用的两个方法:

Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。

bool pop(BuildContext context, [ result ])
将栈顶路由出栈,result为页面关闭时返回给上一个页面的数据。

1.1 路由跳转

比如我们想要跳转到一个叫做New Route的路由,基本写法就是这样的:

NavigatorState navigatorState = Navigator.of(context);
prefix0.MaterialPageRoute materialPageRoute = new MaterialPageRoute(builder: (context){return new NewRoute();});
navigatorState.push(materialPageRoute);
//这段代码和下面的Android中的启动一个Activity很像
Intent intent = new Intent();
intent.setClass(this,MainActivity.class);
startActivity(intent);

再来看下简写的区别:

Navigator.of(context)
      .push(new MaterialPageRoute(builder: (context) {
   return new NewRoute();
}));
----------------------------------------------------------------
startActivity(new Intent(this,MainActivity.class));

但是这样写还是很麻烦,Android中也有封装好的启动一个activity的方式,看下封装的代码:

ActivityUtils.startActivity(MainActivity.class);
这样来说一行代码就能用普通方式启动一个activity。

那Flutter中也有这么简单的启动方式,就是命名路由,所谓命名路由就是先给路由起个名字,等我们想要启动路由的时候,根据这个名字就可以启动这个路由了。以下是如何实现的代码:

return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.orange,
      ),
      //注册路由表
      routes: {
        "路由名称": (context) => new NewRoute(),
        --省略其他路由注册
      },
    );

上面代码中的routes其实就是一个它是一个Map,key为路由的名字,是个字符串;value是个builder回调函数,用于生成相应的路由widget。我们在通过路由名字打开新路由时,应用会根据路由名字在路由表中查找到对应的WidgetBuilder回调函数,然后调用该回调函数生成路由widget并返回。这样我们来看看启动一个命名路由有多简单:

Navigator.pushNamed(context, “路由名称”);

一行代码就可以了,很简单。

1.2 路由传值

如何启动一个路由的时候把数据传过去?
看官方的函数:

 static Future<T> pushNamed<T extends Object>(
    BuildContext context,
    String routeName, {
    Object arguments,
   }) {
    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }

其实就是上面的pushNamed函数,第一个参数是上下文的context,第二个参数是要启动的路由名称,第三个参数就是要传递的数据。看下具体怎么实现:

Navigator.pushNamed(context, "路由名称",arguments: "要传递的数据");

就是再加一个参数,这个参数可以是string可以是int,只要是object的子类就行。那启动的路由怎么接收传递过去的数据呢,看代码:

class 路由名称 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 下面这行代码就是接收传递数据的代码。
    var data = ModalRoute.of(context).settings.arguments;
   --省略其他代码
}

1.3 路由数据回传

如果启动一个路由并且接收此路由关闭时传递回来的数据,怎么实现。这时候就用到开始说的pop函数了
看下官网代码:

static bool pop<T extends Object>(BuildContext context, [ T result ]) {
   return Navigator.of(context).pop<T>(result);
}

此函数就是把栈顶的路由也就是当前页面给移除栈,第一个参数是上下文context,第二个参数就是要回传的数据。看下具体实现:

RaisedButton(
     onPressed: () => Navigator.pop(context, "NewRoute返回的数据"),
     child: Text("返回"),
)

这样这个路由就会关闭且回传数据,那如何接收回传的数据,也很简单,把前面启动的代码稍加改动就可以了,看代码:

onPressed: () async {
       var pushNamed = await Navigator.pushNamed(
       context, StringsConst.ROUTE_NEW,
       arguments: "来自main的数据");
       print("NewRoute返回的数据:$pushNamed");
}

这里使用async/await来等待页面的关闭,pushNamed函数会返回一个var,就是路由回传的数据。
注意:这种方式只有在点击自己添加的返回按钮才会有回传数据,点击AppBar上的返回或者手机自带的返回键返回上一个路由是接收不到数据的,如何实现无论怎么返回都能返回数据,书里没说,后面再看有没有其他办法。

1.4启动新路由关闭当前路由

如果想要启动一个新路由的同时并关闭当前路由,使用下面这三个函数任何一个都可以:

Navigator.of(context).pushReplacementNamed("路由名称");
 --------------------------------------------------------------------------------------                       
Navigator.of(context).pushReplacement(
    new MaterialPageRoute(builder: (context) {
  return new NewRoute();
}));
---------------------------------------------------------------------------------------                        
Navigator.popAndPushNamed(context, "路由名称");

1.5 启动新路由并关闭之前所有路由

还有一种情况,就是当用户退出登录后,到重新登录的路由,这样我们需要关闭所有已有的路由,并启动登录路由,这时候使用下面这个函数:

Future<T> pushNamedAndRemoveUntil<T extends Object>(
    String newRouteName,
    RoutePredicate predicate, {
    Object arguments,
  }) {
    return pushAndRemoveUntil<T>(_routeNamed<T>(newRouteName, arguments: arguments), predicate);
  }

第一个参数:要启动的路由名称。
第二个参数:暂时还不清楚。
第三个参数:要传递的数据。
看下具体实现代码:

Navigator.of(context).pushNamedAndRemoveUntil("路由名称", (Route<dynamic> route) => false);

还有一个函数是关闭所有的路由:

void popUntil(RoutePredicate predicate) {
   while (!predicate(_history.last))
     pop();
}

2 包管理

包其实就是指一些公共的库或SDK,我们想要使用这些公共的包就需要先对这些包有个统一的管理。介绍包管理前先介绍下Flutter中的pubspec.yaml文件,这个文件就是项目的配置文件,来对项目和包进行管理配置。看下这个文件中的默认代码都是什么意思:

# 应用或包名称。
name: first_flutter_app

# 应用或包简介、描述。
description: A new Flutter application.

# 应用或包的版本号。
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

# 应用或包依赖的其它包或插件。
dependencies:
  flutter:
    sdk: flutter

  # 类iOS风格图标
  cupertino_icons: ^0.1.2
  # 常用英文单词以及一些实用功能
  english_words: ^3.1.5

# 开发环境依赖的工具包(而不是flutter应用本身依赖的包)。
dev_dependencies:
  flutter_test:
    sdk: flutter


# flutter相关的配置选项。
flutter:

  uses-material-design: true

上面是一些简单的介绍,其中的:english_words: ^3.1.5。就是我们用到的一个公共包。
这些包都是在pub.dev统一管理的,我们可以在这上面找到我们需要的包。
比如english_words:
在这里插入图片描述
Example是使用例子,Installing是如何安装。
第一步:将english_words: ^3.1.5添加到pubspec.yaml中。
第二步:点击右上角的pub get。
第三步:在使用的route中导包:import ‘package:english_words/english_words.dart’。

3 资源管理

3.1 图片适配

资源管理是指一些图标、图片、字体、html等等的一些管理,这里先简单学一下图标的管理,其他的还要放到后面实际应用的时候再具体的学习怎么使用。
图片资源管理其实也是在pubspec.yaml中注册,Flutter会根据设备屏幕的像素密度来选择加载不同的图片,那不同大小的图片怎么管理,系统才会选择到正确的图片呢,在assets中创建不同倍率的文件夹用来存放对应大小的图片,如图:
在这里插入图片描述
然后在pubspec.yaml中进行注册:
在这里插入图片描述
然后就可以使用,使用的使用不用写2x\3x,系统会自动根据分辨率选择对应的图片:

Image.asset(
     "assets/wxr.jpg",
     width: 200,
     height: 200,
     fit: BoxFit.cover,
),

3.2 修改APP图标和启动页

Android修改APP的图标需要替换图中的图标文件
在这里插入图片描述
iOS修改APP图标需要替换下图中的文件:
在这里插入图片描述
Android修改启动页需要修改下图中的文件:
在这里插入图片描述
iOS修改启动页需要修改下图中的文件:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值