使用Flutter编写应用(五)

本文介绍了如何使用Flutter改进城市列表显示,将其改为宫格布局,并添加卡片效果。同时,讲解了如何实现网络数据的本地文件缓存,确保在没有网络时仍能展示数据。通过这一系列步骤,提升天气应用的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

如果你从第一篇连读到本文,可能你已经把天气app的简易版写出来了,但是数据的缓存或者列表的美观度还是远远不够。本文将对城市列表进行改动并且对获取到的网络数据通过文件缓存起来,在拿不到网络数据的时候使用。

1.修改成宫格

将CityWidget中的build方法返回改成宫格的Widget

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3),//列数
        itemCount: cityList.length,
        itemBuilder: (context, index) {
          return ListTile(
            title:Text(
                          cityList[index].name,
                          style: TextStyle(color: Colors.white, fontSize: 22))
         
              ),
            onTap: () {
              //命名路由
//              Navigator.pushNamed(context, "weather");
              //自定义构建路由
              Navigator.push<String>(context,
                  MaterialPageRoute(builder: (context) =>
                      WeatherWidget(cityList[index].name)))
                  .then((String value) {
                //接收返回的数据
              });
            },
          );
        }
    );

}

2.添加卡片Card:

 @override
  Widget build(BuildContext context) {
    return GridView.builder(
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3),
        itemCount: cityList.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: new Card(
              elevation: 5.0, //阴影大小
              shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(14.0))),
              semanticContainer: true,
              //表示单个语义容器,false表示接收单个child,但该view是包含子级的组件
              child: new Scaffold(
                body: new Stack(
                  fit: StackFit.expand,
                  children: <Widget>[
                    Image.asset("images/item_bg.jpg", fit: BoxFit.fitHeight),
                    Center(
                      child: Text(
                          cityList[index].name,
                          style: TextStyle(color: Colors.white, fontSize: 22)),)
                  ],),
              ),),
            onTap: () {
              //命名路由
//              Navigator.pushNamed(context, "weather");
              //自定义构建路由
              Navigator.push<String>(context,
                  MaterialPageRoute(builder: (context) =>
                      WeatherWidget(cityList[index].name)))
                  .then((String value) {
                //接收返回的数据
              });
            },
          );
        }
    );
}

3.增加缓存

缓存准备存放在本地文件中,需要添加依赖:

path_provider: ^0.5.0+1

在CityData中导入包:

import 'dart:io';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'dart:convert';

创建缓存文件

static Future<File> getCacheFile() async {
  String dir = (await getApplicationDocumentsDirectory()).path;
  return new File('$dir/cities.txt');
}

缓存至本地

static void saveToLocal(String cityListJson) async {
  var file = await getCacheFile();
  file.writeAsString(cityListJson);
}

从本地获取城市列表

static Future<List<CityData>> getCitiesFromLocal() async {
  List<CityData> list = new List();
  try {
    dynamic content = (await getCacheFile()).readAsString();
    var cityJson = await json.decode(content);

    for (dynamic city in cityJson['HeWeather6'][0]['basic']) {
      CityData cityData = CityData(name: city['location']);
      list.add(cityData);
    }
    return list;
  } catch (e) {
    return list;
  }
}

在CityWidget中添加缓存功能

Future<List<CityData>> _futureGetCityList() async {
    ......

    if (response.statusCode == HttpStatus.OK) {
     ......
      //缓存至本地
      CityData.saveToLocal(responseBody);
    }
  } catch (exception) {
    print(exception.toString());
  }

  if (data.isEmpty) {
    //从本地获取
    data.addAll((await CityData.getCitiesFromLocal()));
  }

  return data;
}

结语

到这里宫格+卡片+缓存已经分享结束了,效果还可以,希望看文章的你能够喜欢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值