Flutter實戰2 --- 寫一個天氣查詢的APP

代碼github地址:github.com/koudle/GDG_…git

前面一篇文章Flutter實戰1 --- 寫一個天氣查詢的APP ,實現了一個顯示城市、溫度、天氣、溼度的界面,可是這個界面只有一個顯示的功能,沒有任何可交互的地方,本篇文章繼續完善查詢天氣的APP的功能。github

增長兩個功能:web

  1. 新增一個城市選擇的頁面
  2. 在城市選擇頁面,點擊城市,跳轉到對應城市天氣的頁面

1. 建立城市選擇頁面

在Android中新建一個頁面,須要用Activity,在iOS中須要用ViewController,但在Flutter中,新建一個頁面只須要用Widge就行,因此咱們新建一個CityWidget.dartCityWidget是一個ListView,從服務器拉取城市的列表並顯示,咱們用CityData.dart來存儲城市的數據。代碼以下:json

  • CityData.dart
class CityData{
  String cityName;

  CityData(this.cityName);
}
複製代碼
  • CityWidget.dart

CityWidget是一個StatefulWidget,由於CityWidget裏的數據是從服務器上拉的,是變的,因此須要用StatefulWidget來實現,從服務器拉取數據的代碼和Flutter實戰1 --- 寫一個天氣查詢的APP裏的WeatherWidget同樣,不一樣的是:bash

  1. CityWidget是一個List,用ListView.builder實現,須要填兩個參數itemCount(List數據的個數)和itemBuilder(List中item的view),在itemBuilder中有index的參數,能夠直接從data中去到數據
  2. 爲了讓List的item響應點擊事件,在List的item外面包了一層GestureDetectorGestureDetector也是一個Widget,由於在Flutter裏處理點擊事件的也是一個Widget,因此你想讓你的Widget處理事件,必須得包一層處理事件的Widget,在Widget裏的onTap處理點擊事件
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:gdg_weather/page/city/CityData.dart';
import 'package:gdg_weather/page/weather/WeatherWidget.dart';
import 'package:http/http.dart' as http;

class CityWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return CityState();
  }

}

class CityState extends State<CityWidget>{

  List<CityData> cityList = new List<CityData>();

  CityState(){
    _getCityList();
  }

  void _getCityList() async{
    List<CityData> citys = await _fetchCityList();
    setState(() {
      cityList = citys;
    });
  }

  //拉取城市列表
  Future<List<CityData>> _fetchCityList() async{
    final response = await http.get('https://search.heweather.net/top?group=cn&key=ebb698e9bb6844199e6fd23cbb9a77c5');

    List<CityData> cityList = new List<CityData>();

    if(response.statusCode == 200){
      //解析數據
      Map<String,dynamic> result = json.decode(response.body);
      for(dynamic data in result['HeWeather6'][0]['basic']){
        CityData cityData = CityData(data['location']);
        cityList.add(cityData);
      }
      return cityList;
    }else{
      return cityList;
    }
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ListView.builder(
        itemCount: cityList.length,
        itemBuilder: (context,index){
          return ListTile(
            title: GestureDetector(
              child:  Text(cityList[index].cityName),
              onTap:(){
                Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => WeatherWidget(cityList[index].cityName))
                );
              },
            ),
          );
        });
  }

}
複製代碼

2.路由

要打開一個頁面,Android中是先初始化Intent,而後調用startActivity();在iOS中是先初始化ViewController,而後調用pushViewController;在web裏,是調用一個跳轉連接。服務器

那麼在Dart中如何從一個頁面跳轉到另外一個頁面呢?app

答案就是 路由less

路由有多種實現,這裏給出一個:async

  • 打開一個頁面
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => WeatherWidget(cityList[index].cityName))
);
複製代碼
  • 返回
Navigator.pop(context);
複製代碼

3.WeatheWidget

天氣頁面須要知道上個頁面點擊的是哪一個城市,因此將城市當作WeaterWidget的構造參數傳過來。ide

4.頁面調整

由於咱們想第一個打開的頁面是城市列表,點擊城市列表後,跳轉到天氣頁面,因此調整一下main.dart裏面的代碼,將WeatherWidget改成CityWidget

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: CityWidget(),
      ),
    );
  }
}
複製代碼

5.代碼目錄跳轉

其實到前面一步,功能已經實現,可是由於如今已經有不少類了,如今目錄結構太混亂了,調整一下,以下:

6.運行界面

相關文章
相關標籤/搜索