Membuat Aplikasi Mobile Info Cuaca Menggunakan Data BMKG

Membuat Aplikasi Mobile Info Cuaca Menggunakan Data BMKG

Sobatcoding.com - Membuat aplikasi mobile info cuaca menggunakan data BMKG dengan Flutter

Artikel kali ini kita akan coba membuat sebuah aplikasi mobile info cuaca menggunakan data terbuka dari BMKG. Data BMKG ini bersifat open source dan format XML bisa kalian cek di link berikut https://data.bmkg.go.id/prakiraan-cuaca/.

Contoh data yang kita gunakan kali ini adalah hanya kota Jawa Timur saja. Untuk link source data xmlnya adalah berikut ini

https://data.bmkg.go.id/DataMKG/MEWS/DigitalForecast/DigitalForecast-JawaTimur.xml

 

Buat Project Baru

Buatlah sebuah project flutter baru, contoh flutter cuaca. Tambahkan beberapa dependencies berikut

xml: ^6.1.0
http: ^0.13.5
xml2json: ^5.3.5
weather_icons: ^3.0.0

 

Fetch Data XML dari BMKG

Buatlah sebuah function untuk fetch data XML dari BMKG

Future<List<dynamic>> fetchDataBMKGJatim() async {
    var uRL =
        "https://data.bmkg.go.id/DataMKG/MEWS/DigitalForecast/DigitalForecast-JawaTimur.xml";

    final result = await http.get(Uri.parse(uRL));
    final Xml2Json xml2Json = Xml2Json();
    xml2Json.parse(result.body);
    var json = xml2Json.toGData();

    Map<String, dynamic> map = jsonDecode(json);
    return map['data']['forecast']['area'];
}

 

Display Data

Tampilkan data XML di atas ke dalam listview menggunakan stream builder seperti berikut

Expanded(
                child: FutureBuilder<List<dynamic>>(
                  future: fetchDataBMKGJatim(),
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if (snapshot.hasError) {
                      return Text("${snapshot.error}");
                    }

                    if (snapshot.hasData) {
                      List<dynamic> dataKota = snapshot.data;
                      
                      }
                      return ListView.builder(
                          padding: const EdgeInsets.all(10),
                          itemCount: dataKota.length,
                          itemBuilder: (BuildContext context, int index) {
                            var item = dataKota[index];
                            return buildListKota(item);
                          });
                    } else {
                      return const Center(child: CircularProgressIndicator());
                    }
                  },
                ),
              )

 

Menampilkan Info Cuaca Tiap Kota

Buatlah widget untuk menampilkan detail info cuaca

Map<String, dynamic>? dataHumadity;
Map<String, dynamic>? windDirection;
Map<String, dynamic>? windSpeed;

Map<String, dynamic>? dataTemperature;
Map<String, dynamic>? dataWeather;

@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(
            widget.title,
            style: const TextStyle(fontSize: 18),
          ),
          centerTitle: true,
        ),
        body: Container(
          color: Colors.lightBlue,
          padding: const EdgeInsets.all(10),
          child: Column(
            children: [
              const SizedBox(
                height: 10,
              ),
              Padding(
                padding: const EdgeInsets.all(13.0),
                child: TextField(
                  controller: searchController,
                  onChanged: (value) {
                    setState(() {
                      textSearch = value;
                    });
                  },
                  decoration: const InputDecoration(
                      labelText: 'Cari disini ...',
                      suffixIcon: Icon(Icons.search),
                      fillColor: Colors.white,
                      filled: true,
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(width: 2, color: Colors.white10),
                      ),
                      focusedBorder: OutlineInputBorder(
                        borderSide: BorderSide(width: 2, color: Colors.white38),
                      )),
                ),
              ),
              Container(
                height: 20,
                decoration: const BoxDecoration(
                  border: Border(
                    bottom: BorderSide(width: 0.8, color: Colors.white),
                  ),
                ),
              ),
              Expanded(
                child: FutureBuilder<List<dynamic>>(
                  future: fetchDataBMKGJatim(),
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if (snapshot.hasError) {
                      return Text("${snapshot.error}");
                    }

                    if (snapshot.hasData) {
                      List<dynamic> dataKota = snapshot.data;
                      if (textSearch.isNotEmpty) {
                        dataKota = dataKota.where((element) {
                          return element['description']
                              .toString()
                              .toLowerCase()
                              .contains(textSearch.toString().toLowerCase());
                        }).toList();
                      }
                      return ListView.builder(
                          padding: const EdgeInsets.all(10),
                          itemCount: dataKota.length,
                          itemBuilder: (BuildContext context, int index) {
                            var item = dataKota[index];
                            return buildListKota(item);
                          });
                    } else {
                      return const Center(child: CircularProgressIndicator());
                    }
                  },
                ),
              ),
            ],
          ),
        ));
  }
}

 

Menambahkan Filter

Sebagai tambahan kita akan mencoba menambahkan filter ke dalam stream builder yang telah kita buat. Caranya adalah seperti berikut

Buatlah sebuah widget TextField sebagai input pencarian

Padding(
                padding: const EdgeInsets.all(13.0),
                child: TextField(
                  controller: searchController,
                  onChanged: (value) {
                    setState(() {
                      textSearch = value;
                    });
                  },
                  decoration: const InputDecoration(
                      labelText: 'Cari disini ...',
                      suffixIcon: Icon(Icons.search),
                      fillColor: Colors.white,
                      filled: true,
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(width: 2, color: Colors.white10),
                      ),
                      focusedBorder: OutlineInputBorder(
                        borderSide: BorderSide(width: 2, color: Colors.white38),
                      )),
                ),
              )

Kemudian tambahkan function untuk memproses filter data dari stream builder

if (snapshot.hasData) {
                      List<dynamic> dataKota = snapshot.data;
                      if (textSearch.isNotEmpty) {
                        dataKota = dataKota.where((element) {
                          return element['description']
                              .toString()
                              .toLowerCase()
                              .contains(textSearch.toString().toLowerCase());
                        }).toList();
 }

kode di atas berfungsi untuk mencari index description berdasarkan pencarian yang kita masukkan di widget TextField.

Tambahkan kode di atas di dalam widget stream builder sehingga menjadi seperti berikut

Expanded(
                child: FutureBuilder<List<dynamic>>(
                  future: fetchDataBMKGJatim(),
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if (snapshot.hasError) {
                      return Text("${snapshot.error}");
                    }

                    if (snapshot.hasData) {
                      List<dynamic> dataKota = snapshot.data;
                      if (textSearch.isNotEmpty) {
                        dataKota = dataKota.where((element) {
                          return element['description']
                              .toString()
                              .toLowerCase()
                              .contains(textSearch.toString().toLowerCase());
                        }).toList();
                      }
                      return ListView.builder(
                          padding: const EdgeInsets.all(10),
                          itemCount: dataKota.length,
                          itemBuilder: (BuildContext context, int index) {
                            var item = dataKota[index];
                            return buildListKota(item);
                          });
                    } else {
                      return const Center(child: CircularProgressIndicator());
                    }
                  },
                ),
              )

 

Hasil akhir kode di atas kurang lebih seperti berikut

sobatcoding.com info cuacasobatcoding.com info cuaca

 

Untuk source lengkap kalian bisa cek di link berikut https://github.com/sobatcoding21/cuaca.

Kalian juga bisa custom sesuai dengan kreatifitas kalian

Sekian tutorial kali ini. Jika teman-teman memiliki pertanyaan atau saran mengenai artikel ini, jangan ragu untuk meninggalkan komentar pada form di bawah ini.

Semoga bermanfaat.