Github address: github.com/koudle/GDG_…
This APP contains an interface that displays cities, temperature, weather and humidity. However, this interface has only one display function, without any interaction. This APP improves the function of Flutter, which can query the weather.
Add two features:
- Added a city selection page
- In the city selection page, click on the city to jump to the corresponding city weather page
1. Create a city selection page
To create a page on Android, you need to use an Activity. To create a page on iOS, you need to use a ViewController. But to create a page on Flutter, you only need to use Widge. CityWidget is a ListView that pulls a list of cities from the server and displays them. We use citydata.dart to store the CityData. The code is as follows:
- CityData.dart
class CityData{
String cityName;
CityData(this.cityName);
}
Copy the code
- CityWidget.dart
CityWidget is a StatefulWidget. Because the data in a CityWidget is pulled from the server and is variable, it needs to be implemented with a StatefulWidget. The code to pull data from the server is the same as the WeatherWidget in Flutter Combat 1, which writes a weather query. The difference is that:
- CityWidget is a List that uses
ListView.builder
Implementation, need to fill in two parametersitemCount
(Number of List data) anditemBuilder
(View of the item in List), initemBuilder
There areindex
Can be directly from data to data - In order for the List item to respond to the click event, a layer is wrapped around the List item
GestureDetector
.GestureDetector
This is also a Widget. Because the click event in Flutter is also a Widget, you need to bundle a layer of event handling widgets inside the Widget to allow your Widget to handle eventsonTap
Handling click events
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){// Parse data 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){
returnListTile( title: GestureDetector( child: Text(cityList[index].cityName), onTap:(){ Navigator.push( context, MaterialPageRoute(builder: (context) => WeatherWidget(cityList[index].cityName)) ); },),); }); }}Copy the code
2. The routing
To open a page, Android initializes the Intent and then calls startActivity(). In iOS, we initialize the ViewController, and then we call pushViewController; On the Web, a jump link is called.
So how do you jump from one page to another in Dart?
The answer is routing!
There are several implementations of routing, one of which is given here:
- Open a page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => WeatherWidget(cityList[index].cityName))
);
Copy the code
- return
Navigator.pop(context);
Copy the code
3.WeatheWidget
The weather page needs to know which city the previous page clicked on, so pass in the city as the build parameter for the WeaterWidget.
4. Page adjustment
Dart: “CityWidget” : “CityWidget” : “CityWidget” : “CityWidget” : “CityWidget” : “CityWidget” : “CityWidget” : “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(), ), ); }}Copy the code
5. Code directory jump
In fact, the previous step, the function is already implemented, but because there are already many classes, now the directory structure is too confusing, adjust the following: