【Flutter】开发之实战Widget(四)

栏目: IOS · Android · 发布时间: 6年前

内容简介:首先要在然后进行跳转

Flutter 的页面跳转,主要是通过 Navigator 来实现,类似原生中的路由,分为静态和动态2种方式。

  • 静态

首先要在 MaterialApproutes 中进行注册

MaterialApp(
      routes: {
        'base': (BuildContext context) {
          return BaseDemo();
        },
        'login': (BuildContext context) {
          return LoginDemo();
        }
      },
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.brown,
      ),
      home: MainDemo(),
    );
复制代码

然后进行跳转

RaisedButton(
                child: Text('BaseWidget'),
                onPressed: () {
                  Navigator.pushNamed(context, 'base');
                },
              )
复制代码

这种方式的缺点也比较明显,首先需要注册,其次是不能传递参数

  • 动态

需要构建 MaterialPageRoute

RaisedButton(
                child: Text('PageView'),
                onPressed: () {
                  Navigator.push(context,
                      new MaterialPageRoute(builder: (BuildContext context) {
                    return PageViewDemo();
                  }));
                },
              )
复制代码
  • 关闭页面

主要是通过 pop 方法来实现 Navigator.of(context).pop();

  • 传递参数

首先,需要在目标 Widget 中定义参数

class LoginDemo extends StatefulWidget {
  @override
  _LoginDemoState createState() => _LoginDemoState(tel);

  final String tel;

  LoginDemo({Key key, @required this.tel}) : super(key: key);
}
复制代码

再传递参数

RaisedButton(
                child: Text('Login'),
                onPressed: () {
                  Navigator.push(context,
                      new MaterialPageRoute(builder: (BuildContext context) {
                    return LoginDemo(tel: '18700000000');
                  }));
                },
              )
复制代码

目标 Widget 取值,这里用到的是上一篇中的登录示例,详情可以查看 【Flutter】开发之高级Widget(三)

class _LoginDemoState extends State<LoginDemo> {
  String tel;

  _LoginDemoState(this.tel);

  TextEditingController user = new TextEditingController();
  TextEditingController pwd = new TextEditingController();

  @override
  void initState() {
    super.initState();
    setState(() {
      user.text = tel;
    });
  }
}
复制代码

这里通过 setState 触发 Widget 重新构建刷新,将传递来的值设置给目标 TextField

【Flutter】开发之实战Widget(四)
  • 回传参数

首先是在关闭时,加入参数 Navigator.of(context).pop('0000000'); 接收时,静态和动态方式的参数回传都是通过 then 方法来完成的,这里就以动态方式为例

RaisedButton(
                child: Text('Login'),
                onPressed: () {
                  Navigator.push(context,
                      new MaterialPageRoute(builder: (BuildContext context) {
                    return LoginDemo(tel: '18700000000');
                  })).then((onValue) {
                    buildDialog(context, onValue);
                  });
                },
              )
复制代码
void buildDialog(BuildContext context, String text) {
    showDialog(
      context: context,
      builder: (BuildContext content) {
        return AlertDialog(
          title: Text("提示"),
          content: Text(text),
          actions: <Widget>[
            GestureDetector(
              child: Container(
                child: Text('关闭'),
              ),
              onTap: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }
复制代码
【Flutter】开发之实战Widget(四)

网络请求

flutter 内置 HttpClient 可以用来做网络请求,但是官方建议使用 dio

官方原话: HttpClient 本身功能较弱,很多常用功能都不支持。我们建议您使用 dio 来发起网络请求,它是一个强大易用的dart http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载

我们就从善如流,直接使用 dio 来实现网络请求

pubspec.yaml 文件中添加依赖 dio: ^2.1.4

void getData() {
    Dio dio = new Dio();
    dio.request(
      //使用自己的接口
      'https://***/module/index.php?ctl=user&act=expertList',
      data: {"p", "1"},
    ).then((onValue) {
      print(onValue);
      setState(() {
        jsonString = onValue;
      });
    });
  }
复制代码

关于 dio 的更多用法,请参考 dio 官方文档

将请求返回的数据展示到 Text

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('NetDemo'),
        actions: <Widget>[
          RaisedButton(
            child: Text('发起请求'),
            onPressed: () {
              getData();
            },
          ),
        ],
      ),
      body: Container(
        child: Text('${jsonString}'),
      ),
    );
  }
复制代码
【Flutter】开发之实战Widget(四)

JSON 序列化

上一步中,我们拿到了网络请求返回的 json ,怎么把它转换为对象呢?这就涉及到了序列化

  • 1. flutter 内置的 json ,老版本中为 JSON

首先,添加导入 import 'dart:convert';

void getData() {
    Dio dio = new Dio();
    dio.request(
      'https://***/module/index.php?ctl=user&act=expertList',
      data: {"p", "1"},
    ).then((onValue) {
      print(onValue);
      //dynamic 代表动态数据类型 即可以是数字、字符串等任意类型
      Map<String, dynamic> list = json.decode(onValue.toString());

      setState(() {
        data = list['data'];
      });
    });
  }
复制代码

使用数据

Widget _listView() {
    return ListView.builder(
      itemBuilder: (context, index) {
        return MoveItem(data[index]);
      },
      itemCount: data.length,
    );
  }

class MoveItem extends StatelessWidget {
  var model;

  MoveItem(this.model);

  @override
  Widget build(BuildContext context) {
    return Container(     
            child: Image.network(
              'http://chuangfen.oss-cn-hangzhou.aliyuncs.com' +
                  model['head_image'],
            ),
    );
}
复制代码

虽然说问题解决了,但是这种方式的弊端很明显, 我们直到运行时才知道值的类型,这样会失去了大部分静态类型语言特性:类型安全、自动补全和最重要的编译时异常。这样一来,我们的代码可能会变得非常容易出错。

  • 2.手动序列化

只需要添加 BaseModel ,并传入泛型,在其中添加 json 转对象的方法即可。

添加 BaseModel

import 'dart:convert';

class BaseModel<T> {
  int status;
  String msg;
  T data;

  BaseModel(this.status, this.msg, this.data);

  BaseModel.fromJson(String jsonString) {
    Map<String, dynamic> data = json.decode(jsonString);
    BaseModel(data['status'], data['msg'], data['data']);
  }

  Map<String, dynamic> toJson() => {
        'status': status,
        'msg': msg,
        'data': data,
      };
}
复制代码

添加 ExpertModel

class ExpertModel {
  String nick_name;
  String head_image;
  String id;
  String signature;
}
复制代码

这时,就可以这样使用

void getData() {
    Dio dio = new Dio();
    dio.request(
      'https://www.yfbr2018.com/module/index.php?ctl=user&act=expertList',
      data: {"p", "1"},
    ).then((onValue) {
      BaseModel<List<ExpertModel>> baseModel =
          BaseModel<List<ExpertModel>>.fromJson(onValue.toString());

      setState(() {
        jsonString = onValue;
        data = baseModel.data;
      });
    });
  }

class MoveItem extends StatelessWidget {
  ExpertModel model;

  MoveItem(this.model);

  @override
  Widget build(BuildContext context) {
    return Container(     
            child: Image.network(
              'http://chuangfen.oss-cn-hangzhou.aliyuncs.com' +
                 model.head_image,
            ),
    );
}

复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro Django

Pro Django

Marty Alchin / Apress / 2008-11-24 / USD 49.99

Django is the leading Python web application development framework. Learn how to leverage the Django web framework to its full potential in this advanced tutorial and reference. Endorsed by Django, Pr......一起来看看 《Pro Django》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具