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

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

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

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,
            ),
    );
}

复制代码

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

查看所有标签

猜你喜欢:

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

JSP & Servlet学习笔记

JSP & Servlet学习笔记

【台湾】林信良 / 清华大学出版社 / 2012-5 / 58.00元

本书是作者多年来教学实践经验的总结,汇集了教学过程中学生在学习JSP & Servlet时遇到的概念、操作、应用或认证考试等问题及解决方案。 本书针对Servlet 3.0的新功能全面改版,无论是章节架构与范例程序代码,都做了全面更新。书中详细介绍了Servlet/ JSP与Web容器之间的关系,必要时从Tomcat源代码分析,了解Servlet/ JSP如何与容器互动。本书还涵盖了文本处理......一起来看看 《JSP & Servlet学习笔记》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具