使用Flutter编写应用(二)

前言

上一篇分享了如何搭建界面,但是没涉及到数据的获取与操作。本文将分享如何异步从网络获取数据并显示出来。

开始

1.引入网络请求包和json转换包:

import 'dart:convert';
import 'dart:io';

2.创建数据实体类:

class WeatherData {

  WeatherData({this.city, this.tmp, this.txt});
  String city; //
  int tmp; //温度
  String txt; //天气情况

}
//心情便签
class Notes {
  String text;
  Notes(this.text);
}

3.在WeatherState中添加异步方法,用于从网络获取数据:

//从网络获取天气情况(异步方法)
Future<WeatherData> _fetchWeatherData() async {
  var url = "https://free-api.heweather.net";
  var httpClient = new HttpClient();

  try {
    var uri = new Uri.http(
        url, '/v5/now', /*参数*/{'key': "mykey", 'city': 'myCity'});
    var request = await httpClient.getUrl(uri);

    var response = await request.close();

    if (response.statusCode == HttpStatus.OK) {
      var responseBody = await response.transform(Utf8Decoder()).join();
        //将获取到的数据转换成json数据
      var weatherJson = await json.decode(responseBody);
        //将Json格式数据转换成对应的实体类对象
      var data = WeatherData.fromJson(weatherJson);
      return data;
    } else {
      return WeatherData.getEmpty();
    }
  } catch (exception) {
    return WeatherData.getEmpty();
  }
}

async标记_fetchWeatherData方法为一个异步方法,await是因为后面的执行是异步的,比如await request.close()中close方法是被标为异步的方法。关于网络请求还有其他第三方库,用起来会更方便些,比如: http: ^0.12.0。

此方法虽然返回值为Future,但实际是返回WeatherData类型。

需要知道的是,由于我们使用到了WeatherData类,即使它们处在同一个包中,还是必须引入的。import ‘package:weather_app/weather/weather_data.dart’;

WeatherData中的定义的方法:

//Json数据格式转换
factory WeatherData.fromJson(Map<String, dynamic> map){
  return WeatherData(city: map['HeWeather5'][0]['basic']['city'],
      tmp: map['HeWeather5'][0]['now']['tmp'],
      txt: '天气:${map['HeWeather5'][0]['now']['cond']['txt']}');
}
//获取一个初始的实例
  factory WeatherData.getEmpty(){
    return WeatherData(city: "未知", tmp: 0, txt: "未知");
  }

里边涉及到了Json数据的解析,用起来挺方便的,就是根据一层层的字段获取对应的值。

4.更新数据状态:

有了从网络中获取到的数据,则可进一步赋值,并且更新对应的数据.

//更新天气
  _getWeatherData() async {
    WeatherData result = await _fetchWeatherData();
//更新数据
    setState(() {
      _weatherData = result;
    });
  }

其中setState方法的调用便会更新数据并且刷新页面。

5.将组件中的数据改为动态显示:

 @override
  Widget build(BuildContext context) {
    //Stack可以让子Widget层叠在一起
    return Scaffold(
        body: Stack(
          fit: StackFit.expand,
          children: <Widget>[
            //背景图
            //Image.asset("images/weather_bg.png", fit: BoxFit.fill),
            //显示网络图片
             Image.network("imageUrl")

            //城市
            Container(
              alignment: Alignment.topCenter,
              margin: EdgeInsets.only(top: 40),
              child: Text(
                //广州
                _weatherData.city,
                style: TextStyle(color: Colors.white, fontSize: 20),
                textAlign: TextAlign.start,),
            ),
            //天气情况
            Column(
              mainAxisAlignment: MainAxisAlignment.center, //定位整个Column
              crossAxisAlignment: CrossAxisAlignment.center, //定位子Widget
              children: <Widget>[
                Container(
                  color: Color(0x55FFFFFF),
                  margin: EdgeInsets.only(top: 50),
                  padding: EdgeInsets.all(30),
                  child:
                  Text(
				// "温度:30 °C",
                    //改为动态
                    '温度:${_weatherData.tmp}°C',
                    style: TextStyle(color: Colors.white, fontSize: 30,),
                    textAlign: TextAlign.start,),
                ),
                Container(
                  color: Color(0x55FFFFFF),
                  margin: EdgeInsets.only(top: 10
                  ),
                  padding: EdgeInsets.all(20),
                  child: Text(
				// "天气:阴",
                    _weatherData.txt,
                    style: TextStyle(color: Colors.white, fontSize: 30),
                    textAlign: TextAlign.start,
                  ),)
              ],
            ),

            //生活便签
            Column(
              mainAxisAlignment
                  : MainAxisAlignment.end,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Container(
                  margin
                      : EdgeInsets.all(10),
                  child: Text(
                    "今日便签:",
                    style: TextStyle(color: Colors.white, fontSize: 16),),
                ),
                Container
                  (
                  margin: EdgeInsets.only(bottom: 15, left: 10),
                  child: Text(
				//"放下生活的担子,回归潇洒。",
                    _notes.text,
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                )
              ]
              ,
            )
          ]
          ,
        )
    );
  }

最后便可以动态展示我们所要看的城市的天气情况。同时心情便签也同样的流程去获取。

结语

我们添加了网络请求操作,使得动态显示数据。同时在请求的时候需要标记为异步,并且获取数据后通过setState方法刷新Widget树去更新数据显示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值