代碼github地址:github.com/koudle/GDG_…git
前面一篇文章Flutter實戰1 --- 寫一個天氣查詢的APP ,實現了一個顯示城市、溫度、天氣、溼度的界面,可是這個界面只有一個顯示的功能,沒有任何可交互的地方,本篇文章繼續完善查詢天氣的APP的功能。github
增長兩個功能:web
在Android中新建一個頁面,須要用Activity,在iOS中須要用ViewController,但在Flutter中,新建一個頁面只須要用Widge就行,因此咱們新建一個CityWidget.dart
,CityWidget
是一個ListView,從服務器拉取城市的列表並顯示,咱們用CityData.dart
來存儲城市的數據。代碼以下:json
class CityData{
String cityName;
CityData(this.cityName);
}
複製代碼
CityWidget是一個StatefulWidget,由於CityWidget裏的數據是從服務器上拉的,是變的,因此須要用StatefulWidget來實現,從服務器拉取數據的代碼和Flutter實戰1 --- 寫一個天氣查詢的APP裏的WeatherWidget
同樣,不一樣的是:bash
ListView.builder
實現,須要填兩個參數itemCount
(List數據的個數)和itemBuilder
(List中item的view),在itemBuilder
中有index
的參數,能夠直接從data中去到數據GestureDetector
,GestureDetector
也是一個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))
);
},
),
);
});
}
}
複製代碼
要打開一個頁面,Android中是先初始化Intent
,而後調用startActivity()
;在iOS中是先初始化ViewController
,而後調用pushViewController
;在web裏,是調用一個跳轉連接。服務器
那麼在Dart中如何從一個頁面跳轉到另外一個頁面呢?app
答案就是 路由
!less
路由有多種實現,這裏給出一個:async
Navigator.push(
context,
MaterialPageRoute(builder: (context) => WeatherWidget(cityList[index].cityName))
);
複製代碼
Navigator.pop(context);
複製代碼
天氣頁面須要知道上個頁面點擊的是哪一個城市,因此將城市當作WeaterWidget
的構造參數傳過來。ide
由於咱們想第一個打開的頁面是城市列表,點擊城市列表後,跳轉到天氣頁面,因此調整一下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(),
),
);
}
}
複製代碼
其實到前面一步,功能已經實現,可是由於如今已經有不少類了,如今目錄結構太混亂了,調整一下,以下: