Konsep capaian data dari mobile app ke pangkalan data online melalui format JSON.
capaian data dari mobile app ke pangkalan data online melalui format JSON
IDE: Tutorial Flutter berikut menggunakan IDE VSCode dengan Flutter plugins.
SERVER: Apache/PHP & MySQL (jana data format JSON)
Keperluan server/pangkalan data online
Data dalam server online perlu dijana dalam format JSON seperti rajah di bawah. Alamat URL data ada di https://khirulnizam.com/training/searchflutter.php
JSON formatted training data in searchflutter
Jadual yang digunakan untuk simpan data: training
tablename – training
searchflutter.php
Kod untuk PHP berikut mengandungi arahan JSON_ENCODE untuk menjana data dari database kepada format JSON. (Kod lengkap di GITHUB)
<?php
header('Content-Type: application/json'); //to make json format pretty
// code @GITHUB
// bit.ly/gitjson
// searchflutter.php
include "connect.php";
//keyword
if(!isset($_GET['key']))
$key=null;
else
$key=$_GET['key'];
//generate JSON from table
$traininglist= array();
$response=array();
$sql="SELECT id,trainingname,website, trainingdesc
FROM a_training
WHERE trainingname LIKE '%$key%'
OR trainingdesc LIKE '%$key%' ";
//run query
$rs=mysqli_query($db,$sql);
if($rs==false){
echo mysqli_error($rs);
}
//no record found
if (mysqli_num_rows($rs)==0){
}
else{//found some records
while($rec=mysqli_fetch_array($rs)){
//capture one record
$traininglist=array();
$traininglist["id"] = $rec["id"];
$traininglist["trainingname"] = $rec["trainingname"];
$traininglist["website"] = $rec["website"];
$traininglist["trainingdesc"] = $rec["trainingdesc"];
//push to response
array_push($response, $traininglist);
}//end while
}//end found records
//generate JSON encoded data
//print_r $traininglist;
echo json_encode($response); //output JSON format
?>
Koding Dart/Flutter
pubspec.yaml
Terdapat tambahan kepada fail ini ;
- simple_permissions: “^0.1.2” //uses-permission capaian INTERNE
- http: ^0.12.0+1 //dart API plugin handle HTTP connection
-
url_launcher: ^5.0.0 //buka alamat URL webpage pada browser
name: flutter_json_fetch_data
description: A new Flutter application.
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# Read more about versioning at semver.org.
version: 1.0.0+1
# to allow internet uses-permission
simple_permissions: "^0.1.2"
environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
http: ^0.12.0+1
#to add http service to apps
url_launcher: ^5.0.0
#to provide webpage view
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
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
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.io/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.io/custom-fonts/#from-packages
training.dart
Spesifikasi struktur data rekod TRAINING, yang mengandungi table dengan skema berikut
training(id, trainingname, trainingdesc, website)
class Training {
final String id;
final String trainingname;
final String website;
final String trainingdesc;
//this.website,
//website: json['website'] as String,
Training({this.id, this.trainingname, this.website, this.trainingdesc});
factory Training.fromJson(Map<String, dynamic> json) {
return Training(
id: json['id'] as String,
trainingname: json['trainingname'] as String,
website: json['website'] as String,
trainingdesc: json['trainingdesc'] as String,
);
}
}
listtraining.dart
Kod ini menjana ListItem dan populasikan ListView
import 'package:flutter/material.dart';
import 'training.dart';
import 'package:url_launcher/url_launcher.dart';
class ListViewTrainings extends StatelessWidget {
final List<Training> trainings;
ListViewTrainings({Key key, this.trainings}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
itemCount: trainings.length,
padding: const EdgeInsets.all(15.0),
itemBuilder: (context, position) {
return Column(
children: <Widget>[
Divider(height: 5.0),
ListTile(
title: Text(
'${trainings[position].trainingname}',
style: TextStyle(
fontSize: 22.0,
color: Colors.deepOrangeAccent,
),
),
subtitle: Text(
'${trainings[position].trainingdesc}',
style: new TextStyle(
fontSize: 18.0,
fontStyle: FontStyle.italic,
),
),
leading: Column(
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.blueAccent,
radius: 35.0,
child: Text(
'${trainings[position].id}',
style: TextStyle(
fontSize: 22.0,
color: Colors.white,
),
),
)
],
),
//onTap: () => _onTapItem(context, trainings[position])
onTap: ()=> _launchURL('${trainings[position].website}'),
),
],
);
}),
);
}
void _onTapItem(BuildContext context, Training training) {
Scaffold
.of(context)
.showSnackBar(
new SnackBar(content: new Text(training.id + ' - ' + training.trainingname))
);
}
_launchURL(String website) async {
String url = website;
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}
main.dart
Fail dart utama untuk set appTitle dan theme
import 'package:flutter/material.dart';
import 'home.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appTitle = 'TrainingFSTM';
return MaterialApp(
title: appTitle,
theme: ThemeData(
// Define the default Brightness and Colors
brightness: Brightness.dark,
primaryColor: Colors.lightBlue[800],
accentColor: Colors.cyan[600],
// Define the default Font Family
fontFamily: 'Montserrat',
// Define the default TextTheme. Use this to specify the default
// text styling for headlines, titles, bodies of text, and more.
textTheme: TextTheme(
headline: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
title: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
body1: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
),
),
home: HomePage(title: appTitle),
);
}
}
home.dart
Paparan laman pertama di mana capaian ke server akan dibuat, dan ListView akan dipaparkan.
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'training.dart';
import 'listtrainings.dart';
Future<List<Training>> fetchTrainings(http.Client client) async {
//fetch JSON data from server
final response = await client.get('http://khirulnizam.com/training/searchflutter.php');
//
return compute(parseTrainings, response.body);//capture data body
}
List<Training> parseTrainings(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
//return data in linked list
return parsed.map<Training>((json) => Training.fromJson(json)).toList();
}
class HomePage extends StatelessWidget {
final String title;
HomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder<List<Training>>(
future: fetchTrainings(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ListViewTrainings(trainings: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
);
}
}
Kod lengkap ada di bit.ly/gitjson
Penulis tutorial:
KHIRULNIZAM ABD RAHMAN, Pensyarah Jabatan Sains Komputer, FSTM KUIS.
Beliau merupakan seorang trainer dalam bidang pengaturcaraan server dan antaramuka web (web front-end & backend) semenjak tahun 2000. Disamping itu juga amat berminat dalam pembangunan applikasi mobile Android, JSON, LARAVEL dan PHP-MySQL.
Blog peribadi beliau di khirulnizam.com . Beliau boleh dihubungi melalui email khirulnizam@gmail.com , atau Whatsapp: http://wasap.my/60129034614