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

寫一個查詢天氣的demo。android

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

1.建立工程

在Android Studio中,File -> New ->New Flutter Project -> Flutter Applicationgit

建立完工程後,有三個目錄github

android:Android工程的目錄shell

ios:iOS工程的目錄json

lib: Flutter工程的目錄api

其中android、ios下的文件咱們都不動,咱們只改動lib目錄下的dart文件。bash

2.運行Flutter工程

  1. 鏈接手機
  • 這裏不建議用模擬器,由於模擬器在用GPU渲染時可能會出問題,致使圖片渲染不出來。
  1. 而後按Run 在手機上把程序跑起來。

3.天氣API接口申請

註冊地址console.heweather.com/registerapp

註冊完後,再看API文檔 www.heweather.com/documentsless

demo這裏用的是,獲取當每天氣狀況的API:www.heweather.com/documents/a…

用的請求URL以下:

https://free-api.heweather.com/s6/weather/now?location=廣州&key=******
複製代碼

4.界面編寫

在建立的工程裏,有個main.dart裏面有一段顯示界面的代碼以下:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or press Run > Flutter Hot Reload in a Flutter IDE). Notice that the
        // counter didn't reset back to zero; the application is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
複製代碼

其中home 就是要顯示的界面,這裏咱們要把MyHomePage換成咱們本身的。

4.1 建立WeatherWidget

經過 new -> Dart File 在lib目錄下建立WeatherWidget

class WeatherWidget extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new WeatherState();
  }
}

class WeatherState extends State<WeatherWidget>{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
    );
  }            
}
複製代碼

建立完後,在main.dart中將home改成WeatherWidget,以下:

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: WeatherWidget(),
    );
  }
複製代碼

4.2 HotReload

在寫UI的工程中,咱們能夠用到Flutter的hot reload的特性,寫佈局的時候,按ctrl+scmd+s就能夠在手機上實時看到界面的變化。

這個功能很好用。

4.3添加圖片資源

Flutter能夠添加不一樣的資源,例如圖片、文本、配置文件、靜態數據等。

添加資源時,須要在pubspec.yaml文件中的flutter屬性下添加assets,並標明要添加資源的路徑,例如,咱們要加入指定的圖片時,能夠這麼寫:

flutter:
 assets:
 - assets/my_icon.png
 - assets/background.png
複製代碼

若是要添加的資源太多,也能夠添加文件夾,例如:

flutter:
 assets:
 - assets/
複製代碼

在本demo中,要添加一個背景圖,咱們在工程的根目錄下建立images目錄,將背景圖放在images目錄下,而後在pubspec.yaml中添加:

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
 uses-material-design: true
 assets:
 - images/
複製代碼

4.4 寫WeatherWidget的UI佈局

Scaffold中添加body的屬性,來寫UI的佈局,以下:

class WeatherState extends State<WeatherWidget>{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: new Stack(
        fit: StackFit.expand,
        children: <Widget>[
          new Image.asset("images/weather_bg.jpg",fit: BoxFit.fitHeight,),
          new Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              new Container(
                width: double.infinity,
                margin: EdgeInsets.only(top: 40.0),
                child: new Text(
                  "廣州市",
                  textAlign: TextAlign.center,
                  style: new TextStyle(
                    color: Colors.white,
                    fontSize: 30.0,
                  ),
                ),
              ),
              new Container(
                width: double.infinity,
                margin: EdgeInsets.only(top: 100.0),
                child: new Column(
                  children: <Widget>[
                    new Text(
                        "20 °",
                        style: new TextStyle(
                            color: Colors.white,
                            fontSize: 80.0
                        )),
                    new Text(
                        "晴",
                        style: new TextStyle(
                            color: Colors.white,
                            fontSize: 45.0
                        )),
                    new Text(
                      "溼度 80%",
                      style: new TextStyle(
                          color: Colors.white,
                          fontSize: 30.0
                      ),
                    )
                  ],
                ),
              )
            ],
          )
        ],
      ),
    );
  }

}
複製代碼

ctrl+s,在手機上就能夠看到寫好的UI,但這時候的數據是寫死的,下來看如何經過http獲取數據。

5.經過http獲取數據

要經過http數據,咱們首先要添加http的依賴庫,在pubspec.yaml中的dependencies添加以下:

dependencies:
 flutter:
 sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
 cupertino_icons: ^0.1.2
 http: ^0.12.0
複製代碼

而後在當前工程目錄下運行如下命令行:

$ flutter packages get
複製代碼

或者在Android Stuido 打開pubspec.yaml 文件,點擊上面的packages get

這裏操做的意義是,拉取http的庫。

5.1 建立WeatherData類

經過 new -> Dart File 在lib目錄下建立WeatherData

class WeatherData{
  String cond; //天氣
  String tmp; //溫度
  String hum; //溼度

  WeatherData({this.cond, this.tmp, this.hum});

  factory WeatherData.fromJson(Map<String, dynamic> json) {
    return WeatherData(
      cond: json['HeWeather6'][0]['now']['cond_txt'],
      tmp: json['HeWeather6'][0]['now']['tmp']+"°",
      hum: "溼度 "+json['HeWeather6'][0]['now']['hum']+"%",
    );
  }

  factory WeatherData.empty() {
    return WeatherData(
      cond: "",
      tmp: "",
      hum: "",
    );
  }
}
複製代碼

5.2 數據獲取

class WeatherState extends State<WeatherWidget>{

  WeatherData weather = WeatherData.empty();

  WeatherState(){
    _getWeather();
  }

  void _getWeather() async{
    WeatherData data = await _fetchWeather();
    setState((){
      weather = data;
    });
  }

  Future<WeatherData> _fetchWeather() async{
    final response = await http.get('https://free-api.heweather.com/s6/weather/now?location=廣州&key=ebb698e9bb6844199e6fd23cbb9a77c5');
    if(response.statusCode == 200){
      return WeatherData.fromJson(json.decode(response.body));
    }else{
      return WeatherData.empty();
    }
  }



  @override
  Widget build(BuildContext context) {
    ...
  }
}  
複製代碼

5.3 將以前寫死的數據換成WeatherData

...                
                child: new Column(
                  children: <Widget>[
                    new Text(
                        weather?.tmp,
                        style: new TextStyle(
                            color: Colors.white,
                            fontSize: 80.0
                        )),
                    new Text(
                        weather?.cond,
                        style: new TextStyle(
                            color: Colors.white,
                            fontSize: 45.0
                        )),
                    new Text(
                      weather?.hum,
                      style: new TextStyle(
                          color: Colors.white,
                          fontSize: 30.0
                      ),
                    )
                  ],
                ),
                ...
複製代碼

6.運行界面

iOS運行界面

Android運行界面
相關文章
相關標籤/搜索