Halo semuanya, kembali lagi di sahretech. Pada kesempatan yang berbahagia kali ini kita akan belajar bagaimana cara membuat aplikasi cek resi sederhana yang sangat bermanfaat di flutter. Penasaran?, ayo ikuti tutorialnya di bawah ini.
Sebelumnya saya sudah membuat aplikasi cek ongkir dengan flutter. Klik tautan berikut ini untuk membaca https://www.sahretech.com/2022/04/cara-mudah-membuat-aplikasi-cek-ongkir.html. Untuk melengkapi pembelajaran kita sebelumnya kita akan membuat aplikasi cek resi dengan api dari binderbyte.com. Aplikasi yang akan dibuat hanya satu buah halaman. Terdapat form input resi, form input kurir, tombol aksi dan hasilnya akan ditampilkan di bagian bawah. Scroll ke bagian paling bawah artikel ini untuk melihat hasil akhirnya.
Cara Membuat Aplikasi Cek Resi di Flutter
import 'dart:convert';
import 'package:http/http.dart' as http;
class Api {
final apiKey =
'4c4a69010dbd67661bb9f53359b06738658e02d1bde2a0eee4de11a12eaf4868';
Future<Map<String, dynamic>> cekResi(String kurir, String resi) async {
var response = await http.get(
Uri.parse(
'https://api.binderbyte.com/v1/track?api_key=${apiKey}&courier=${kurir}&awb=${resi}',
),
);
return json.decode(response.body);
}
}
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'api.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Aplikasi Cek Resi',
home: FlutterFirstApp(),
));
}
class FlutterFirstApp extends StatefulWidget {
const FlutterFirstApp({Key? key}) : super(key: key);
@override
State<FlutterFirstApp> createState() => _FlutterFirstAppState();
}
class _FlutterFirstAppState extends State<FlutterFirstApp> {
//tambahkan nama kurir lain untuk membuat pilihan yang lebih banyak
List<String> options = ['jne', 'pos', 'tiki', 'sicepat', 'jnt'];
TextEditingController resiController = TextEditingController();
TextEditingController kurirController = TextEditingController();
dynamic data = []; //untuk menampung data yang didapatkan
bool _isLoading = false; //berfungsi sebagai indikator loading
Api api = Api(); //inisialisasi class Api, karena kita akan menggunakan methodnya
//method untuk mengambil data
Future<void> cekResi() async {
setState(() {
_isLoading = true;
});
final result = await api.cekResi(
kurirController.text,
resiController.text,
);
setState(() {
data = result;
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Cek Resi'),
),
body: ListView(
padding: EdgeInsets.all(16),
children: [
Row(
children: [
Flexible(
//flexible adalah widget yang berfungsi untuk memberikan lebar porsi pada sebuah widget
//kita membuat lebar textformfield sebesar 4, sehingga lebarnya lebih lebar dari
//dropdownbuttonfield
flex: 4,
child: TextFormField(
decoration: InputDecoration(
hintText: 'Resi',
labelText: 'Resi',
),
controller: resiController,
),
),
SizedBox(
width: 10,
),
Flexible(
//flexible adalah widget yang berfungsi untuk memberikan porsi lebar pada sebuah widget
//kita membuat lebar dropdownbuttonfield sebesar 2, sehingga lebarnya lebih kecil dari
//textformfield
flex: 2,
child: DropdownButtonFormField<String>(
items: options.map((String option) {
return DropdownMenuItem<String>(
value: option,
child: Text(option),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
kurirController.text = newValue!;
});
},
decoration:
InputDecoration(hintText: 'Kurir', labelText: 'Kurir'),
),
),
],
),
SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
setState(() {
_isLoading = true; // Aktifkan indikator progress
});
cekResi();
},
child: _isLoading
? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white,
), // Ganti warna di sini
) // Tampilkan indikator saat isLoading true
: Text('Cari Resi'),
),
SizedBox(
height: 20,
),
Text(
'Hasil Pengecekan',
style: TextStyle(fontSize: 20),
),
SizedBox(
height: 20,
),
//jika data tidak kosong dan status 200
data.isNotEmpty && data['status'] == 200
? Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Resi: ${data['data']['summary']['awb']}', //tampilkan resi
style: TextStyle(fontSize: 16),
),
Divider(),
Text(
'Kurir: ${data['data']['summary']['courier']}', //tampilkan kurir
style: TextStyle(fontSize: 16),
),
Divider(),
Text(
'Resi: ${data['data']['summary']['status']}', //tampilkan status pengiriman
style: TextStyle(fontSize: 16),
),
Divider(),
//kita akan menampilkan history
ListView.builder(
shrinkWrap:
true, //wajib menggunakan ini saat parentnya adalah listview
physics:
NeverScrollableScrollPhysics(), //wajib menggunakan ini sat parentnya adalah listview
itemCount: data['data']['history']
.length, //panjang data history
itemBuilder: (context, index) {
final item = data['data']['history'][index];
return Column(
children: [
ListTile(
contentPadding: EdgeInsets.zero,
title:
Text('${item['date']}'), //tanggal history
subtitle:
Text('${item['desc']}'), //deskripsi history
),
Divider()
],
);
},
),
],
)
//pokoknya jika data kosong atau tidak 200 maka tampilkan teks ini
: Text('Belum Ada Data ditemukan')
],
),
),
);
}
}
No comments
Jangan lupa kasih komentar ya!. Karena komentar kalian membantu kami menyediakan informasi yang lebih baik
Tidak boleh menyertakan link atau promosi produk saat berkomentar. Komentar tidak akan ditampilkan. Hubungi 081271449921(WA) untuk dapat menyertakan link dan promosi