flutter 第五天(温故页面布局 然后实现网络请求)

今天继续写页面 温故下之前的 并且看看有没有 知新0.0

在不使用默认的tabbar的情况下 做出来可以左右滑动的二级列表(类似tabbar的)

开始~~~~~

老铁们 温故温故 就是温柔的用故(guo)去的知识 哈哈哈哈 (小朋友们不要相信 刚刚那句话是给搬砖的人看的 你们都是祖国未来的花朵 要记住 温故而知新的意思是:温习已学的知识,并且由其中获得新的领悟 爱学习的小朋友可以点击这里查看更多)
是的 我们不使用默认的tabbar 怎样做出来可以类似tabbar的左右滑动的二级列表呢
其实很多小朋友已经想到了 列表列表 就是要用列表啊
所以 我们不使用默认的tabbar 怎样做出来可以类似tabbar的左右滑动的二级列表呢
就是用 横向的ListView 哈哈哈哈哈哈 惊不惊喜 意不意外

开始温故~~~~~

其实关键代码就是这一行

scrollDirection:Axis.horizontal

但是要做出来选中效果的哦

在布局的时候出现了这个错误


image.png

解决中
解决完毕 解决方法就不说了 太尴尬这个 一点点的问题 太马虎了 这里记个教训 希望老铁们不要马虎 实在想知道 评论区见0.0

new Container(
            padding: const EdgeInsets.only(top: 8,left: 5,right: 5,bottom: 8),
            height: ScreenUtil().setHeight(46),
            child:  new ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: secondList.length,
                itemBuilder: (BuildContext context,int index){
                  return text(index);
                }
            )
        ),
 Widget text(int index){
    return new Container(
      padding: const EdgeInsets.only(left: 10,top: 6,bottom: 6,right: 10),
      margin: const EdgeInsets.only(left: 10),
      height: ScreenUtil().setHeight(26),
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(3.0),
          color: Colors.red
      ),
      child: new Text(secondList[index],style: new TextStyle(
          fontSize: 13,
          color: Colors.white
      ),
        textAlign: TextAlign.center,),
    );
  }

这样就完成了可以横向滑动的ListView
下面写选中状态

选中状态的话 把第一段代码换成

 int currentNum = 0;
  Widget text(int index){
    Color backColor = Color.fromRGBO(248, 248, 248, 1);
    Color textColor = Colors.black;
    if(currentNum == index){
      backColor = Color.fromRGBO(227, 36, 32, 1);
      textColor = Colors.white;
    }
    return new GestureDetector(
      child: new Container(
        padding: const EdgeInsets.only(left: 10,top: 6,bottom: 6,right: 10),
        margin: const EdgeInsets.only(left: 10),
        height: ScreenUtil().setHeight(26),
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(3.0),
            color: backColor
        ),
        child: new Text(secondList[index],style: new TextStyle(
            fontSize: 13,
            color: textColor
        ),
          textAlign: TextAlign.center,),
      ),
      onTap: (){
        currentNum = index;
        setState(() {

        });
      },
    );
  }

也就是把row的代码加上状态和点击事件就行了

页面传值一:

子页面:

class NewList extends StatefulWidget {
  const NewList(Key key, {
    this.titles
  }) : super(key: key);
  final List<String> titles;
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new Page();
  }
}


class Page extends State<NewList> {
@override
  Widget build(BuildContext context) {
    ScreenUtil.instance = ScreenUtil(width: value.desginWidth, height: value.desginHeight)..init(context);
    print(widget.titles);
    return layout(context);
  }
}

父页面:

NewList(new Key(""),titles: ["通知","公告"],),//通知公告

网络请求

网络请求 可以使用三方库也可以使用flutter自己官方的类库

官方的网络请求
var httpClient = new HttpClient();
  var url = Constant.baseUrl + Controller + Action;

  _loadData() async {
    try {
      var request = await httpClient.getUrl(Uri.parse(url));
      var response = await request.close();
      if (response.statusCode == HttpStatus.OK) {
        _result = await response.transform(UTF8.decoder).join();
        //这里解析数据
      } else {
        _result = 'error code : ${response.statusCode}';
      }
    } catch (exception) {
      _result = '网络异常';
    }

    // If the widget was removed from the tree while the message was in flight,
    // we want to discard the reply rather than calling setState to update our
    // non-existent appearance.
    if (!mounted) return;

    setState(() {});
  }

本文主要记录第三方库dio的使用方法

Flutter中文网推荐的第三方库dio

image.png

dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等...

必须要先添加依赖

在pubspec.yaml文件里面添加
dependencies:
  dio: ^x.x.x  // 请使用pub上的最新版本  https://pub.dev/packages/dio

一个非常简单的例子

Dio dio = new Dio();
Response response=await dio.get("https://www.google.com/");
print(response.data);

当然了 你必须要引入包

在对应的文件里面引入
import 'package:dio/dio.dart';

请耐心看完 或者直接往下翻 到 <我的实例>

发起一个 GET 请求 :

Response response;
response=await dio.get("/test?id=12&name=wendu")
print(response.data.toString());
// 请求参数也可以通过对象传递,上面的代码等同于:
response=await dio.get("/test",data:{"id":12,"name":"wendu"})
print(response.data.toString());

发起一个 POST 请求:

response=await dio.post("/test",data:{"id":12,"name":"wendu"})

发起多个并发请求:

response= await Future.wait([dio.post("/info"),dio.get("/token")]);

下载文件:

response=await dio.download("https://www.google.com/","./xx.html")

发送 FormData:

FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
});
response = await dio.post("/info", data: formData)

通过FormData上传多个文件:

FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
   "file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt"),
   "file2": new UploadFileInfo(new File("./upload.txt"), "upload2.txt"),
     // 支持文件数组上传
   "files": [
      new UploadFileInfo(new File("./example/upload.txt"), "upload.txt"),
      new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
    ]
});
response = await dio.post("/info", data: formData)

创建一个Dio实例,并配置它
你可以使用默认配置或传递一个可选 Options参数来创建一个Dio实例 :

Dio dio = new Dio; // 使用默认配置

// 配置dio实例
dio.options.baseUrl="https://www.xx.com/api"
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout=3000;

// 或者通过传递一个 `options`来创建dio实例
Options options= new Options(
    baseUrl:"https://www.xx.com/api",
    connectTimeout:5000,
    receiveTimeout:3000
);
Dio dio = new Dio(options);

请求配置项 默认是get请求

{
  /// Http method.
  String method;

  /// 请求基地址,可以包含子路径,如: "https://www.google.com/api/".
  String baseUrl;

  /// Http请求头.
  Map<String, dynamic> headers;

  /// 连接服务器超时时间,单位是毫秒.
  int connectTimeout;

  ///  响应流上前后两次接受到数据的间隔,单位为毫秒。如果两次间隔超过[receiveTimeout],
  ///  [Dio] 将会抛出一个[DioErrorType.RECEIVE_TIMEOUT]的异常.
  ///  注意: 这并不是接收数据的总时限.
  int receiveTimeout;

  /// 请求数据,可以是任意类型.
  var data;

  /// 请求路径,如果 `path` 以 "http(s)"开始, 则 `baseURL` 会被忽略; 否则,
  /// 将会和baseUrl拼接出完整的的url.
  String path="";

  /// 请求的Content-Type,默认值是[ContentType.JSON].
  /// 如果您想以"application/x-www-form-urlencoded"格式编码请求数据,
  /// 可以设置此选项为 `ContentType.parse("application/x-www-form-urlencoded")`,  这样[Dio]
  /// 就会自动编码请求体.
  ContentType contentType;

  /// [responseType] 表示期望以那种格式(方式)接受响应数据。
  /// 目前 [ResponseType] 接受三种类型 `JSON`, `STREAM`, `PLAIN`.
  ///
  /// 默认值是 `JSON`, 当响应头中content-type为"application/json"时,dio 会自动将响应内容转化为json对象。
  /// 如果想以二进制方式接受响应数据,如下载一个二进制文件,那么可以使用 `STREAM`.
  ///
  /// 如果想以文本(字符串)格式接收响应数据,请使用 `PLAIN`.
  ResponseType responseType;

  /// `validateStatus` 决定http响应状态码是否被dio视为请求成功, 返回`validateStatus`
  ///  返回`true` , 请求结果就会按成功处理,否则会按失败处理.
  ValidateStatus validateStatus;

  /// 用户自定义字段,可以在 [Interceptor]、[Transformer] 和 [Response] 中取到.
  Map<String, dynamic> extra;
}

响应数据
当请求成功时会返回一个Response对象,它包含如下字段:

{
  /// 响应数据,可能已经被转换了类型, 详情请参考Options中的[ResponseType].
  var data;
  /// 响应头
  HttpHeaders headers;
  /// 本次请求信息
  Options request;
  /// Http status code.
  int statusCode;
  /// 响应对象的自定义字段(可以在拦截器中设置它),调用方可以在`then`中获取.
  Map<String, dynamic> extra;
}

示例如下:

Response response=await dio.get("https://www.google.com");
print(response.data);
print(response.headers);
print(response.request);
print(statusCode);

拦截器
每一个 Dio 实例都有一个请求拦截器 RequestInterceptor 和一个响应拦截器 ResponseInterceptor, 通过拦截器你可以在请求之前或响应之后(但还没有被 then 或 catchError处理)做一些统一的预处理操作。

 dio.interceptor.request.onSend = (Options options){
     // 在请求被发送之前做一些事情
     return options; //continue
     // 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`对象或返回`dio.resolve(data)`。
     // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义数据data.
     //
     // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,或返回`dio.reject(errMsg)`,
     // 这样请求将被中止并触发异常,上层catchError会被调用。
 }
 dio.interceptor.response.onSuccess = (Response response) {
     // 在返回响应数据之前做一些预处理
     return response; // continue
 };
 dio.interceptor.response.onError = (DioError e){
     // 当请求失败时做一些预处理
     return e;//continue
 }

如果你想移除拦截器,你可以将它们置为null:

dio.interceptor.request.onSend=null;
dio.interceptor.response.onSuccess=null;
dio.interceptor.response.onError=null;

上面的来自lazyou想了解更多可以去看看

我的实例

我使用的是聚合数据的接口

FormData formData = new FormData.from({
      "type": "top",
      "key": "这个是我在聚合数据上申请的key",
    });
    String url = "http://v.juhe.cn/toutiao/index";
    Dio dio = new Dio();
    Response response = await  dio.post(url,data:formData);
    print(response.toString());

返回的json

{reason: 成功的返回, result: {stat: 1, data: [{uniquekey: 166143cb8d958c3a0611f7119e011d4c, title: 上海国际水展“2019年好喝中国净水行业创新峰会”正式开幕, date: 2019-06-03 16:26, category: 头条, author_name: 中国新闻网, url: http://mini.eastday.com/mobile/190603162637961.html, thumbnail_pic_s: http://09imgmini.eastday.com/mobile/20190603/20190603162637_ccf1324729c750cb8ca4ae9627f02b4d_6_mwpm_03200403.jpg, thumbnail_pic_s02: http://09imgmini.eastday.com/mobile/20190603/20190603162637_ccf1324729c750cb8ca4ae9627f02b4d_3_mwpm_03200403.jpg, thumbnail_pic_s03: http://09imgmini.eastday.com/mobile/20190603/20190603162637_ccf1324729c750cb8ca4ae9627f02b4d_4_mwpm_03200403.jpg}, {uniquekey: 2af0e385dff1d98150b8586c5a5b5f8c, title: 中国海军第31批护航编队访问澳大利亚, date: 2019-06-03 16:22, category: 头条, author_name: 央视网, url: http://mini.eastday.com/mobile/190603162219489.html, thumbnail_pic_s: http://00imgmini.eastday.com/mobile/20190603/20190603162219_71be

现在还只是字符串 由于字符太多 不能完全显示(有那个小伙伴知道flutter的debug跟Android的debug一样可以在断点处显示值并且可以复制请告诉我)

这个是封装了下网络请求之后的方式

 FormData formData = new FormData.from({
      "type": "top",
      "key": "这个是我在聚合数据上申请的key",
    });
    String url = "http://v.juhe.cn/toutiao/index";
    Map response = await HttpHelper.getInstance().post(url,data: formData);
    print(response);

现在开始解析

JSON解析
使用 dart:convert手动序列化JSON
Flutter中基本的JSON序列化非常简单。Flutter有一个内置dart:convert库,其中包含一个简单的JSON编码器和解码器。
这个是在聚合上复制下来的格式 先按照这个格式创建I个model

{
    "reason":"成功的返回",
    "result":{
        "stat":"1",
        "data":[
            {
                "uniquekey":"6c4caa0c3ba6e05e2a272892af43c00e",
                "title":"杨幂的发际线再也回不去了么?网友吐槽像半秃",
                "date":"2017-01-05 11:03",
                "category":"yule",
                "author_name":"腾讯娱乐",
                "url":"[http://mini.eastday.com/mobile/170105110355287.html?qid=juheshuju](http://mini.eastday.com/mobile/170105110355287.html?qid=juheshuju)",
                "thumbnail_pic_s":"[http://03.imgmini.eastday.com/mobile/20170105/20170105110355_806f4ed3fe71d04fa452783d6736a02b_1_mwpm_03200403.jpeg](http://03.imgmini.eastday.com/mobile/20170105/20170105110355_806f4ed3fe71d04fa452783d6736a02b_1_mwpm_03200403.jpeg)",
                "thumbnail_pic_s02":"[http://03.imgmini.eastday.com/mobile/20170105/20170105110355_806f4ed3fe71d04fa452783d6736a02b_2_mwpm_03200403.jpeg](http://03.imgmini.eastday.com/mobile/20170105/20170105110355_806f4ed3fe71d04fa452783d6736a02b_2_mwpm_03200403.jpeg)",
                "thumbnail_pic_s03":"[http://03.imgmini.eastday.com/mobile/20170105/20170105110355_806f4ed3fe71d04fa452783d6736a02b_3_mwpm_03200403.jpeg](http://03.imgmini.eastday.com/mobile/20170105/20170105110355_806f4ed3fe71d04fa452783d6736a02b_3_mwpm_03200403.jpeg)"
            }
        ]
    }
}

TestModel.dart

class TestModel{
  String uniquekey;
  String title;
  String date;
  String category;
  String author_name;
  String url;
  String thumbnail_pic_s;
  String thumbnail_pic_s02;
  String thumbnail_pic_s03;
  TestModel(){
    uniquekey = "";
    title = "";
    date = "";
    category = "";
    author_name = "";
    url = "";
    thumbnail_pic_s = "";
    thumbnail_pic_s02 = "";
    thumbnail_pic_s03 = "";
  }

  TestModel.fromJson(Map<String,dynamic> json) :
        uniquekey = json["uniquekey"],
        title = json["title"],
        date = json["date"],
        category = json["category"],
        author_name = json["author_name"],
        url = json["url"],
        thumbnail_pic_s = json["thumbnail_pic_s"],
        thumbnail_pic_s02 = json["thumbnail_pic_s02"],
        thumbnail_pic_s03 = json["thumbnail_pic_s03"];
}
  //网络请求测试
  Future testNet() async {
    FormData formData = new FormData.from({
      "type": "top",
      "key": "e94932dd98ca1d577d365c26daafadac",
    });
    String url = "http://v.juhe.cn/toutiao/index";
    Map response = await HttpHelper.getInstance().post(url,data: formData);
    if(response["result"]["data"] is List){
      List maps = response["result"]["data"];
      for(int i = 0; i < maps.length ; i++){
        TestModel model = TestModel.fromJson(maps[i]);
        models.add(model);
      }
      print(models[0].title);
    }
  }
}

这样是可以的 但是感觉很麻烦
在网上找了一个json_serializable 库 准备试试

在按照步奏 运行flutter packages pub run build_runner build的时候出现错误

image.png

求大神帮忙看下
引入的包已经引入了 安装的第三方也安装了
这个问题先放下 暂时不影响使用 明天继续

上一篇------------------------------------下一篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • 自用收藏 原文:http://www.th7.cn/Program/IOS/201606/884245.shtml...
    西瓜皮奥特曼阅读 2,181评论 0 16
  • 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图...
    万忍阅读 1,500评论 0 6
  • 会有歌唱30岁的女人,为什么没有歌唱一唱25岁的女人呢? 我的25岁,已经觉得自己到了一个尴尬的年纪,谈过的恋爱,...
    火红的兔子阅读 276评论 0 1
  • 效果图非常壮观,制作的时候分为三个大的部分:首先根据透视关系做出立体字,并给文字增加纹理;然后截取素材合成到文字的...
    a104b284f747阅读 496评论 1 2
  • 有时候生活容不得一点偷懒,你在这里捡的便宜偷的懒,有一日必将连本带利的归还,不肯对生活付出的人,生活也会拒绝给他付...
    毛毛咻咻萌萌阅读 161评论 0 0