代码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(),
),
);
}
}
复制代码
其实到前面一步,功能已经实现,可是由于如今已经有不少类了,如今目录结构太混乱了,调整一下,以下: