flutter memungkinkan kita untuk membuat aplikasi yang ... · flutter adalah teknologi untuk...
TRANSCRIPT
Flutter adalah teknologi untuk membangun suatu mobile apps yang dibuat oleh
Google. Dengan menggunakan Flutter, Anda dapat membuat aplikasi Android dan
iOS sekaligus. Flutter menggunakan bahasa Dart yang juga dibuat oleh Google dan
merupakan bahasa general purpose. Artinya, Dart mampu berjalan di banyak
platform.
Flutter merupakan cross-platform framework, alias aplikasi yang dapat digunakan
di lebih dari satu platform. Aplikasi yang dibuat dengan menggunakan Flutter dapat
dijalankan baik di platform Android maupun iOS. Tentu hal ini akan menghemat
waktu. Anda pun tidak perlu mempelajari bahasa native yang digunakan di masing-
masing platform.
Keunggulan Flutter :
• Flutter memungkinkan kita untuk membuat aplikasi yang indah (beautiful)
• Flutter berjalan dengan sangat cepat (fast)
• Flutter sangat produktif (productive)
• Flutter bersifat terbuka (opensource)
Apa bedanya membuat aplikasi android menggunakan Android Studio (native)
dengan Flutter?
• hot reload
• Flutter menggunakan bahasa pemrograman Dart
• Aplikasi yang kita buat dengan Flutter dapat di-build ke Android dan iOS.
Contoh aplikasi yang dibangun dengan flutter :
• Alibaba (Android);
• Google AdWords (Android);
• App Tree (Android);
• Topline (Android);
• Hamilton (Android dan iOS);
Tools yang perlu dipersiapkan
• Java Development Kit (JDK);
• Android Studio;
• Android SDK;
• Flutter SDK;
• Teks Editor (atau bisa juga pakai Android Studio).
Kebutuhan dasar software
• Operating Systems: Windows 7 SP1 or later (64-bit)
• Disk Space: 400 MB (does not include disk space for IDE/tools).
• Tools: Flutter depends on these tools being available in your environment.
• Windows PowerShell 5.0 or newer (this is pre-installed with Windows 10)
• Git for Windows 2.x, with the Use Git from the Windows Command Prompt
option.
Cara download Flutter SDK
• https://storage.googleapis.com/flutter_infra/releases/stable/windows/flutter_
windows_v1.7.8+hotfix.4-stable.zip
• Extract zip file dan simpan flutter pada installation location Flutter SDK
(Contoh, C:\src\flutter; Jangan diletakan pada folder yang membutuhkan hak
akses sistem ! )
• Jalankan file flutter_console.bat dalam flutter directory
Update Path SDK
• Buka konfigurasi “Environment Variable”.
• Tambahkan pada user variable:
– Jika belum ada, tambahkan full path flutter\bin
Menjalankan Flutter Doctor
Sebelum kita membuat aplikasi dengan Flutter, kita perisksa dulu kesiapan peralatan
yang kita install.
Silahkan ketik perintah berikut untuk memeriksanya:
• Jalankan flutter doctor dari Fluuter Console Command prompt:
– C:\src\flutter\flutter console
– Ketik :
• Flutter doctor
• Apabila tampila centang seperti ini:
Berarti, Flutter sudah siap digunakan untuk membuat aplikasi Android.
Bila kamu mendapatkan masalah seperti:
• Library yang dibutuhkan belum terinstall di komputer kita;
• Android SDK tidak dapat terdeteksi oleh Flutter
• dll.
Biasanya akan ada saran link yang harus dibuka dan perintah yang harus
diketik. Error tersebut disebabkan karena saya belum menyetujui lisensi
Android SDK. Di sana saya diminta untuk mengetik perintah flutter doctor
--android-licences.
Membuat aplikasi Flutter dengan Android Studio
1. Buka Aplikasi Android Studio
5. Tentukan nama domain, biasanya diberi nama perusahaan (TIDAK
DISARANKAN MENGGUNAKAN DOMAIN EXAMPLE.COM)
Struktur Direktori Flutter
android berisi source code untuk aplikasi android;
ios berisi source code untuk aplikasi iOS;
lib berisi source code Dart, di sini kita akan menulis kode aplikasi;
test berisi source code Dart untuk testing aplikasi;
.gitignore adalah file Git;
.metadata merupakan file yang berisi metadata project yang di-generate
otomatis;
.packages merupakan file yang berisi alamat path package yang dibuat oleh
pub;
flutter_app.iml merupakan file XML yang berisi keterangan project;
pubspec.lock merupakan file yang berisi versi-versi library atau package. File
ini dibuat oleh pub. Fungsinya untuk mengunci versi package.
pubspec.yaml merupakan file yang berisi informasi tentang project dan
libraray yang dibutuhkan;
README.md merupakan file markdown yang berisi penjelasan tentang
source code.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
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: Center(child: MyHomePage(title: 'Aplikasi Flutter')),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
1. Bagian Import
Bagian import adalah tempat kita mendeklarasikan atau mengimpor library yang
dibutuhkan pada aplikasi.
2. Bagian Main
Bagian main adalah fungsi utama dari aplikasi yang akan menjadi entri point.
Fungsi ini akan dieksekusi pertama kali saat aplikasi dibuka.
3. Bagian Widget
Bagian widget adalah tempat kita membuat widget. Aplikasi Flutter sebenarnya
terdiri dari susunan widget. Widget bisa kita bilang elemen-elemen seperti
Tombol, Teks, Layaout, Image, dan sebagainya.
Sebuah widget dapat berisi widget.
StatelessWidget adalah class widget yang propertinya immutable, artinya
nilainya tidak bisa diubah.
Cara membuat StatelessWidget adalah dengan membuat class turunan (extends)
dari class StatelessWidget.
Pada aplikasi di atas, kita membuat StatelessWidget yang berisi widget
MaterialApp(). Kemudian di dalam MateralApp() berisi widget lagi: Scaffold,
AppBar, Center, dan Text.
MyApp adalah StatelessWidget, merupakan widget induk;
MaterialApp adalah widget yang membungkus beberapa widget yang
menggunakan tema material design 1;
Scaffold adalah widget untuk struktur dasar material design;
AppBar adalah widget untuk membuat AppBar;
Center adalah Widget layout untuk membuat widget ke tengah;
Text adalah wdiget untuk membuat teks.
App Bar
AppBar mungkin bisa disinonimkan dengan tag <header> pada HTML, sebab
AppBar merupakan fungsi untuk membuat head dari sebuah aplikasi, dimana
didalamnya terdapat title yang dapat digunakan untuk menampilkan brand atau
page apa yang sedang dibuka dari aplikasi tersebut.
Mengatur Layout Dengan Row & Column
Row() & Column() dapat digunakan untuk mengatur posisi dari widget yang akan
ditampilkan. Row sendiri berarti baris, maka apapun yang diapit oleh class ini
akan menggunakan posisi baris atau berderet kesamping (Horizontal). Sedang
Column berarti kolom, maka widget yang berada didalamnya akan tersusun
kebawah (Vertical).
Lab Layout (Mengatur penggunaan Row dan Column)
import 'package:flutter/material.dart';
void main(){
runApp(new MaterialApp
title:"Layouts",
home: new HalamanSatu(),
));
}
class HalamanSatu extends StatelessWidget{
@override
Widget build (BuildContext context){
return new Scaffold(
backgroundColor: Colors.yellow[200],
appBar: new AppBar(
backgroundColor: Colors.red[900],
leading: new Icon(Icons.home),
title: new Center(child: new Text("Inixindo")),
actions : <Widget>[
new Icon(Icons.search)
]
),
body: new Container(
child : new Column(
children: <Widget>[
new Icon(
Icons.local_airport,
size:80 ,
color: Colors.white),
new Icon(Icons.donut_large,
size : 80,
color: Colors.red),
new Icon(Icons.add_call,
size : 80,
color: Colors.red),
new Row(
children: <Widget>[
new Icon(Icons.computer,
size : 80,
color: Colors.red),
new Icon(Icons.headset,
size : 80,
color: Colors.red),
],
),
new Icon(Icons.add_comment,
size : 80,
color: Colors.red),
],
)
)
);
}
}
Card & Passing Data
Card Merupakan layout manager yang mampu menciptakan efek “Tumpukan”
komponen. Atrinya, layout ini tidak memposisikan komponen dilokasi-lokasi
tertentu didalam container, melainkan menampilkannya satu demi satu. CardLayout
merupakan tata letak berguna ketika kita ingin menyembunyikan dan menampilkan
komponen dalam satu kelompok.
Objek CardLayout adalah layout manager untuk sebuah container.
Penggunaan Cardlayout biasanya untuk membuat panel yang bersifat custom-
tabbed.
Dalam lab kali ini kita akan coba melakukan passing data dari sebuah Class
menuju objek dalam Card
import 'package:flutter/material.dart';
void main(){
runApp(new MaterialApp(
title:"Card & Passing Data",
home: new HalamanSatu(),
));
}
class HalamanSatu extends StatelessWidget{
@override
Widget build (BuildContext context){
return new Scaffold(
appBar: new AppBar(title: new Text("Card & Passing
Data"),),
body: new Container(
child : new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new CardSaya(icon: Icons.home,
teks:"Home",warnaIcon: Colors.brown),
new CardSaya(icon: Icons.add_photo_alternate,
teks:"Photo", warnaIcon: Colors.red),
new CardSaya(icon: Icons.add_shopping_cart,
teks:"Cart",warnaIcon: Colors.green),
],
)
)
) ;
}
}
class CardSaya extends StatelessWidget{
CardSaya({this.icon, this.teks, this.warnaIcon});
final IconData icon;
final String teks;
final Color warnaIcon;
@Override
Widget build(BuildContext context){
return new Container(
padding: new EdgeInsets.all(10),
child: new Card(
child:
new Column(
children: <Widget>[
new Icon(icon, size: 50.0, color: warnaIcon,),
new Text(teks ,style: new TextStyle(fontSize:
20)),
],
)
),
);
}
}
Lab Perpindahan halaman (Intent)
-File Main.dart
import 'package:flutter/material.dart';
import './komputer.dart' as komputer;
import './laptop.dart' as laptop;
import './headset.dart' as headset;
void main(){
runApp(new MaterialApp(
home: new Home(),
title: "Tab Bar"
));
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with
SingleTickerProviderStateMixin{
TabController controller;
@override
void initState() {
// TODO: implement initState
controller = new TabController(vsync:this,length:3);
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.red,
title: new Text("My List"),
bottom: new TabBar(
controller: controller,
tabs: <Widget>[
new Tab(icon: new Icon(Icons.computer),text:
"Computer",),
new Tab(icon: new Icon(Icons.laptop),text:
"Laptop"),
new Tab(icon: new
Icon(Icons.headset),text:"Headset"),
],
)
),
body: new TabBarView(
controller: controller,
children: <Widget>[
new komputer.Komputer(),
new laptop.Laptop(),
new headset.Headset(),
],
),
bottomNavigationBar: new Material(
color: Colors.red,
child: new TabBar(
controller: controller,
tabs: <Widget>[
new Tab(icon: new Icon(Icons.computer),),
new Tab(icon: new Icon(Icons.laptop),),
new Tab(icon: new Icon(Icons.headset),),
],
)
)
);
}
}
Kemudian buat kembali beberapa file .dart lainnya
komputer.dart
import 'package:flutter/material.dart';
class Komputer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(20),),
new Text("Halaman Computer", style: new
TextStyle(fontSize: 30)),
new Icon(Icons.computer,size:90),
],
)
)
);
}
}
laptop.dart
import 'package:flutter/material.dart';
class Laptop extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(20),),
new Text("Halaman Laptop", style: new
TextStyle(fontSize: 30)),
new Icon(Icons.laptop,size:90),
],
)
)
);
}
}
headset.dart
import 'package:flutter/material.dart';
class Headset extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(20),),
new Text("Halaman Headset", style: new
TextStyle(fontSize: 30)),
new Icon(Icons.headset,size:90),
],
)
)
);
}
}
ListView
ListView adalah tampilan beberapa item dalam bentuk list yang dapat di scroll
secara vertikal. Setiap item akan otomatis dimasukkan kedalam list menggunakan
Adapter yang datanya di ambil dari array/database/json/dsb. ListView sering
digunakan dalam aplikasi Android, seperti kontak, email, twitter, dsb.
Adapter adalah jembatan antara dan AdapterView (contohnya ListView) dengan
data. Adapter inilah yang menyediakan akses ke item data dan juga bertanggung
jawab untuk membuat sebuah View pada setiap item dalam kumpulan data. Selain
itu Adapter juga yang mengelola data model. Jadi, dunia ini butuh adapter.
Lab Adapter
import 'package:flutter/material.dart';
void main(){
runApp(new MaterialApp(
home: new Home(),
title: "List View"
));
}
class Home extends StatelessWidget{
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.red,
title: new Text("List"),
),
body: new ListView(
children: <Widget>[
// new ListTile(
// leading: new Icon(Icons.speaker),
// title: new Text("Speaker")
// ),
// new ListTile(
// leading: new Icon(Icons.computer),
// title: new Text("Computer")
// ),
new
ListTutorial(gambar:"https://upload.wikimedia.org/wikipedia/comm
ons/1/17/Google-flutter-logo.png",judul:"Flutter"),
new
ListTutorial(gambar:"https://upload.wikimedia.org/wikipedia/comm
ons/thumb/a/a7/React-icon.svg/1200px-React-
icon.svg.png",judul:"React"),
new
ListTutorial(gambar:"https://logikapagi.files.wordpress.com/2018
/08/codeigniter-logo-png-
transparent.png?w=863&h=0&crop=1",judul:"Codeigniter"),
new
ListTutorial(gambar:"https://upload.wikimedia.org/wikipedia/comm
ons/thumb/c/cf/Angular_full_color_logo.svg/250px-
Angular_full_color_logo.svg.png",judul:"Angular"),
new
ListTutorial(gambar:"https://vuejs.org/images/logo.png",judul:"V
ueJS"),
new
ListTutorial(gambar:"https://upload.wikimedia.org/wikipedia/comm
ons/thumb/6/61/HTML5_logo_and_wordmark.svg/1200px-
HTML5_logo_and_wordmark.svg.png",judul:"HTML 5"),
new
ListTutorial(gambar:"https://www.edureka.co/blog/wp-
content/uploads/2018/09/Golang-Logo-Golang-Tutorial-
Edureka.jpg",judul:"Go Lang"),
],
),
);
}
}
class ListTutorial extends StatelessWidget {
ListTutorial({this.gambar, this.judul});
final String judul;
final String gambar;
@override
Widget build(BuildContext context) {
return new Container(
padding: new EdgeInsets.all(20),
child: new Center(
child: new Row(
children: <Widget>[
new Image(image: new
NetworkImage(gambar),width:70),
new Container(
child: new Center(
child: new Column(
children: <Widget>[
new Text("Tutorial "+judul,style:
new TextStyle(fontSize: 20,color:Colors.green)),
],
)
)
)
],
)
)
);
}
}
Membuat List dengan ListView Builder
import 'package:flutter/material.dart';
void main(){
runApp(new MaterialApp(
home: new Home(data: new List<String>.generate(300,
(i)=>"Data ke $i")),
title: "List View"
));
}
class Home extends StatelessWidget{
final List<String> data;
Home({this.data});
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(title: new Text("List View")),
body: new Container(
child: new ListView.builder(
itemCount: data.length,
itemBuilder: (context,index){
return new ListTile(
leading: new Icon(Icons.widgets),
title: new Text("${data[index]}"),
);
}
),
)
);
}
}
Membuat ListView dengan data JSON
JSON (JavaScript Object Notation) adalah format pertukaran data yang ringan,
mudah dibaca dan ditulis oleh manusia, serta mudah diterjemahkan dan dibuat
(generate) oleh komputer. Format ini dibuat berdasarkan bagian dari Bahasa
Pemprograman JavaScript, Standar ECMA-262 Edisi ke-3 - Desember 1999. JSON
merupakan format teks yang tidak bergantung pada bahasa pemprograman apapun
karena menggunakan gaya bahasa yang umum digunakan oleh programmer keluarga
C termasuk C, C++, C#, Java, JavaScript, Perl, Python dll. Oleh karena sifat-sifat
tersebut, menjadikan JSON ideal sebagai bahasa pertukaran-data.
JSON terbuat dari dua struktur:
Kumpulan pasangan nama/nilai. Pada beberapa bahasa, hal ini dinyatakan sebagai
objek (object), rekaman (record), struktur (struct), kamus (dictionary), tabel hash
(hash table), daftar berkunci (keyed list), atau associative array.
Daftar nilai terurutkan (an ordered list of values). Pada kebanyakan bahasa, hal ini
dinyatakan sebagai larik (array), vektor (vector), daftar (list), atau urutan (sequence).
Struktur-struktur data ini disebut sebagai struktur data universal. Pada dasarnya,
semua bahasa pemprograman moderen mendukung struktur data ini dalam bentuk
yang sama maupun berlainan. Hal ini pantas disebut demikian karena format data
mudah dipertukarkan dengan bahasa-bahasa pemprograman yang juga berdasarkan
pada struktur data ini.
Objek adalah sepasang nama/nilai yang tidak terurutkan. Objek dimulai dengan
{kurung kurawal buka dan diakhiri dengan }kurung kurawal tutup. Setiap nama
diikuti dengan :titik dua dan setiap pasangan nama/nilai dipisahkan oleh ,koma.
Larik adalah kumpulan nilai yang terurutkan. Larik dimulai dengan [kurung kotak
buka dan diakhiri dengan ]kurung kotak tutup. Setiap nilai dipisahkan oleh ,koma.
Nilai (value) dapat berupa sebuah string dalam tanda kutip ganda, atau angka, atau
true atau false atau null, atau sebuah objek atau sebuah larik. Struktur-struktur
tersebut dapat disusun bertingkat.
String adalah kumpulan dari nol atau lebih karakter Unicode, yang dibungkus
dengan tanda kutip ganda. Di dalam string dapat digunakan backslash escapes "\"
untuk membentuk karakter khusus. Sebuah karakter mewakili karakter tunggal pada
string. String sangat mirip dengan string C atau Java.
Lab Membuat ListView dengan menggunakan data JSON
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
void main(){
runApp(new MaterialApp(
home: new Home(),
title: "List View"
));
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List dataJSON;
Future<String> ambildata() async{
http.Response hasil= await http.get(
Uri.encodeFull("https://jsonplaceholder.typicode.com/posts"),hea
ders:{
"Accept":"application/json"
}
);
this.setState((){
dataJSON = json.decode(hasil.body);
});
}
@override
void initState(){
this.ambildata();
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("JSON Data"),),
body: new ListView.builder(
itemCount: dataJSON==null ? 0: dataJSON.length,
itemBuilder: (context,i){
return new Card(
child: new Text(
dataJSON[i]['title'],
style : new TextStyle(fontSize: 20,
color:Colors.redAccent)
)
);
},
)
);
}
}
Lab membuat ListView dengan multiple column
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
void main(){
runApp(new MaterialApp(
home: new Home(),
title: "List View"
));
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List dataJSON;
Future<String> ambildata() async{
http.Response hasil= await http.get(
Uri.encodeFull("https://jsonplaceholder.typicode.com/posts"),hea
ders:{
"Accept":"application/json"
}
);
this.setState((){
dataJSON = json.decode(hasil.body);
});
}
@override
void initState(){
this.ambildata();
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("JSON Data"),),
body: new ListView.builder(
itemCount: dataJSON==null ? 0: dataJSON.length,
itemBuilder: (context,i){
return
new Container(
padding: new EdgeInsets.all(10),
child:new Card(
child: new Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Text(
dataJSON[i]['title'],
style : new TextStyle(fontSize:
20, color:Colors.blue)
),
new Text(
dataJSON[i]['body'],
style : new TextStyle(fontSize:
Inputan, Alert dan Snackbar
TextField adalah widget input teks yang paling umum digunakan. Secara default,
TextField dihiasi dengan garis bawah. Anda dapat menambahkan label, ikon, teks
petunjuk sebaris, dan teks kesalahan dengan memasok InputDecoration sebagai
properti dekorasi dari TextField. Untuk menghapus dekorasi seluruhnya (termasuk
garis bawah dan ruang yang disediakan untuk label), atur dekorasi ke nol.
Alert Dialog adalah sebuah pop up yang muncul pada saat-saat tertentu dan
berfungsi untuk memberi info pada pengguna, berbentuk kotak. Pada tutorial ini kita
akan membuat Alert Dialog sederhana / bawaan dari Android, AlertDialog basic ini
berisi icon (default-nya kosong), title dialog, pesan yang ingin disampaikan dialog
itu, dan tombol “Yes” atau “No” yang bisa dicustom.
SnackBar adalah view baru yang ada di Android Material Design yang mempunyai
fungsi hampir sama seperti Toast, yaitu menampilkan informasi atau pesan singkat
untuk pengguna. Bedanya, SnackBar mempunyai posisi default pada bagian bawah
layar ketika tampil. Selain itu SnackBar tidak hanya memberikan informasi/pesan
kepada pengguna, namun SnackBar juga mempunyai tombol “Action” yang ketika
diklik oleh pengguna akan melakukan suatu aksi yang sudah kita definisikan
sebelumnya.
import 'package:flutter/material.dart';
void main(){
runApp(new MaterialApp(
home: new Home(),
title: "Input Text"
));
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String teks="";
TextEditingController controllerInput = new
TextEditingController();
TextEditingController controllerAlert = new
TextEditingController();
TextEditingController controllerSnack = new
TextEditingController();
void _alertdialog(String str){
if(str.isEmpty) return;
AlertDialog alertDialog = new AlertDialog(
content: new Text(str,style: new TextStyle(fontSize:
20),),
actions: <Widget>[
new RaisedButton(
color: Colors.deepPurple,
child: new Text("OK"),
onPressed: (){
Navigator.pop(context);
},
)
],
);
showDialog(context: context, child: alertDialog);
}
final GlobalKey<ScaffoldState> _scaffoldState = new
GlobalKey<ScaffoldState>();
void _snackbar(String str){
if(str.isEmpty)return;
_scaffoldState.currentState.showSnackBar(new SnackBar(
content: new Text(str,style: new TextStyle(fontSize:
20),),
duration: new Duration(seconds: 3),)
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldState,
appBar: new AppBar(title : new Text("Form Input")),
body: new Container(
child: new Column(
children: <Widget>[
new TextField(
controller: controllerInput,
decoration: new InputDecoration(
hintText: "Input TextField"
),
onSubmitted: (String str){
setState((){
teks = str + "\n" +teks;
controllerInput.text="";
});
},
),
new Text(teks, style: new TextStyle(fontSize:
18),),
new TextField(
controller: controllerAlert,
decoration: new InputDecoration(
hintText: "Alert Dialog"
),
onSubmitted: (String str){
_alertdialog(str);
controllerAlert.text="";
},
),
new TextField(
controller: controllerSnack,
decoration: new InputDecoration(
hintText: "Snack Bar "
),
onSubmitted: (String str){
_snackbar(str);
controllerSnack.text="";
},
),
],
)
)
);
}
}
Navigation Drawer Menu
Navigation Drawer adalah panel yang menampilkan pilihan navigasi utama aplikasi
dari tepi kiri layar. Tersembunyi sebagian, tetapi menu akan muncul ketika
pengguna gesekan jari dari tepi kiri layar atau pengguna menyentuh ikon aplikasi di
bar untuk menampilkannya.
Lab File Navigation Drawer
import 'package:flutter/material.dart';
void main(){
runApp(new MaterialApp(
home: new Home(),
title: "Input Text"
));
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String gambar1 =
"https://awsimages.detik.net.id/visual/2014/11/03/45f5eef5-1c50-
496f-9f00-b6afe62a22da_169.jpg?w=650";
String gambar2 =
"https://www.google.com/url?sa=i&source=images&cd=&ved=2ahUKEwiW
p5ShmuvjAhVw4HMBHZjnAfMQjRx6BAgBEAU&url=https%3A%2F%2Fid.aliexpr
ess.com%2Fitem%2FKnitting-Needles-NEW-3D-Diamond-Painting-full-
square-drill-wall-decor-Mosaic-Embroidery-Series-Inlaid-
craft%2F32360787325.html&psig=AOvVaw1rxuu9w_Gt3HtWowzGbqyb&ust=1
565076414769532";
String gambarx;
String nama1 ="Nazar Firman";
String nama2 ="Firas Fitrada";
String namax;
String email1 = "[email protected]";
String email2 = "[email protected]";
String emailx;
void gantiuser(){
this.setState((){
gambarx = gambar1;
gambar1 = gambar2;
gambar2 = gambarx;
namax = nama1;
nama1 = nama2;
nama2 = namax;
emailx = email1;
email1 = email2;
email2 = emailx;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("Navigation
Drawer")),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text(nama1),
accountEmail: new Text(email1),
currentAccountPicture:
new CircleAvatar(
backgroundImage: new
NetworkImage(gambar1)),
otherAccountsPictures: <Widget>[
new GestureDetector(
onTap:()=> gantiuser(),
child : new
CircleAvatar(backgroundImage: new NetworkImage(gambar2),)
)
],
),
new ListTile(
title : new Text("Setting"),
trailing: new Icon(Icons.settings),
),
new ListTile(
title : new Text("Exit"),
trailing: new Icon(Icons.exit_to_app),
)
],
)
),
body: new Container(
)
);
}
}
Local Database menggunakan SQLite
Banyak opsi media penyimpanan yang bisa kita pakai untuk menyimpan data ke
dalam aplikasi Android, menggunakan database SQLite adalah salah satu opsi yang
paling serbaguna dan praktis untuk kita implementasikan.
Database SQLite adalah solusi penyimpanan yang baik jika anda memiliki data
terstruktur yang perlu diakses dan disimpan secara persisten serta sering ditelusuri
dan diubah. Anda juga bisa menggunakan SQLite sebagai media penyimpanan
utama untuk data aplikasi atau pengguna, atau anda juga bisa menggunakannya
untuk proses caching serta menyediakan data yang diambil dari cloud.
Secara umum, Flutter tidak menyediakan Class SQLite, Tetapi Flutter mendukung
modul open source SQFlite. SQFlite adalah cara menyimpan data aplikasi di
Aplikasi Flutter. SQFlite adalah plugin Database untuk flutter.
Pada Lab SQLite, kita akan Bersama – sama membuat beberapa file diantara lain
file untuk database helper, models, dan masing – masing file untuk operasi CRUD
user.dart
class User {
int id;
String _firstName;
String _lastName;
String _dob;
User(this._firstName, this._lastName, this._dob);
User.map(dynamic obj) {
this._firstName = obj["firstname"];
this._lastName = obj["lastname"];
this._dob = obj["dob"];
}
String get firstName => _firstName;
String get lastName => _lastName;
String get dob => _dob;
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
map["firstname"] = _firstName;
map["lastname"] = _lastName;
map["dob"] = _dob;
return map;
}
void setUserId(int id) {
this.id = id;
}
}
database_helper.dart
import 'dart:async';
import 'dart:io' as io;
import 'package:flutter_database/User.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new
DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async {
if (_db != null) return _db;
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async {
io.Directory documentsDirectory = await
getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "main.db");
var theDb = await openDatabase(path, version: 1, onCreate:
_onCreate);
return theDb;
}
void _onCreate(Database db, int version) async {
// When creating the db, create the table
await db.execute(
"CREATE TABLE User(id INTEGER PRIMARY KEY, firstname
TEXT, lastname TEXT, dob TEXT)");
}
Future<int> saveUser(User user) async {
var dbClient = await db;
int res = await dbClient.insert("User", user.toMap());
return res;
}
Future<List<User>> getUser() async {
var dbClient = await db;
List<Map> list = await dbClient.rawQuery('SELECT * FROM
User');
List<User> employees = new List();
for (int i = 0; i < list.length; i++) {
var user =
new User(list[i]["firstname"], list[i]["lastname"],
list[i]["dob"]);
user.setUserId(list[i]["id"]);
employees.add(user);
}
print(employees.length);
return employees;
}
Future<int> deleteUsers(User user) async {
var dbClient = await db;
int res =
await dbClient.rawDelete('DELETE FROM User WHERE id = ?',
[user.id]);
return res;
}
Future<bool> update(User user) async {
var dbClient = await db;
int res = await dbClient.update("User", user.toMap(),
where: "id = ?", whereArgs: <int>[user.id]);
return res > 0 ? true : false;
}
}
add_user_dialog.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_database/database_hepler.dart';
import 'package:flutter_database/User.dart';
class AddUserDialog {
final teFirstName = TextEditingController();
final teLastFirstName = TextEditingController();
final teDOB = TextEditingController();
User user;
static const TextStyle linkStyle = const TextStyle(
color: Colors.blue,
decoration: TextDecoration.underline,
);
Widget buildAboutDialog(
BuildContext context, _myHomePageState, bool isEdit, User
user) {
if (user != null) {
this.user=user;
teFirstName.text = user.firstName;
teLastFirstName.text = user.lastName;
teDOB.text = user.dob;
}
return new AlertDialog(
title: new Text(isEdit ? 'Edit' : 'Add new User'),
content: new SingleChildScrollView(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
getTextField("Enter first name", teFirstName),
getTextField("Enter last name", teLastFirstName),
getTextField("DD-MM-YYYY", teDOB),
new GestureDetector(
onTap: () {
addRecord(isEdit);
_myHomePageState.displayRecord();
Navigator.of(context).pop();
},
child: new Container(
margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0,
0.0),
child: getAppBorderButton(
isEdit?"Edit":"Add",
EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0)),
),
),
],
),
),
);
}
Widget getTextField(
String inputBoxName, TextEditingController
inputBoxController) {
var loginBtn = new Padding(
padding: const EdgeInsets.all(5.0),
child: new TextFormField(
controller: inputBoxController,
decoration: new InputDecoration(
hintText: inputBoxName,
),
),
);
return loginBtn;
}
Widget getAppBorderButton(String buttonLabel, EdgeInsets
margin) {
var loginBtn = new Container(
margin: margin,
padding: EdgeInsets.all(8.0),
alignment: FractionalOffset.center,
decoration: new BoxDecoration(
border: Border.all(color: const Color(0xFF28324E)),
borderRadius: new BorderRadius.all(const
Radius.circular(6.0)),
),
child: new Text(
buttonLabel,
style: new TextStyle(
color: const Color(0xFF28324E),
fontSize: 20.0,
fontWeight: FontWeight.w300,
letterSpacing: 0.3,
),
),
);
return loginBtn;
}
Future addRecord(bool isEdit) async {
var db = new DatabaseHelper();
var user = new User(teFirstName.text, teLastFirstName.text,
teDOB.text);
if (isEdit) {
user.setUserId(this.user.id);
await db.update(user);
} else {
await db.saveUser(user);
}
}
}
list.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_database/add_user_dialog.dart';
import 'package:flutter_database/User.dart';
import 'package:flutter_database/home_presenter.dart';
class UserList extends StatelessWidget {
List<User> country;
HomePresenter homePresenter;
UserList(
List<User> this.country,
HomePresenter this.homePresenter, {
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return new ListView.builder(
itemCount: country == null ? 0 : country.length,
itemBuilder: (BuildContext context, int index) {
return new Card(
child: new Container(
child: new Center(
child: new Row(
children: <Widget>[
new CircleAvatar(
radius: 30.0,
child: new
Text(getShortName(country[index])),
backgroundColor: const
Color(0xFF20283e),
),
new Expanded(
child: new Padding(
padding: EdgeInsets.all(10.0),
child: new Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Text(
country[index].firstName +
" " +
country[index].lastName,
// set some style to text
style: new TextStyle(
fontSize: 20.0,
color:
Colors.lightBlueAccent),
),
new Text(
"DATE: " + country[index].dob,
// set some style to text
style: new TextStyle(
fontSize: 20.0, color:
Colors.amber),
),
],
),
),
),
new Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
new IconButton(
icon: const Icon(
Icons.edit,
color: const Color(0xFF167F67),
),
onPressed: () =>
edit(country[index], context),
),
new IconButton(
icon: const
Icon(Icons.delete_forever,
color: const Color(0xFF167F67)),
onPressed: () =>
homePresenter.delete(country[index]),
),
],
),
],
),
),
padding: const EdgeInsets.fromLTRB(10.0, 0.0,
0.0, 0.0)),
);
});
}
displayRecord() {
homePresenter.updateScreen();
}
edit(User user, BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) =>
new AddUserDialog().buildAboutDialog(context, this,
true, user),
);
homePresenter.updateScreen();
}
String getShortName(User user) {
String shortName = "";
if (!user.firstName.isEmpty) {
shortName = user.firstName.substring(0, 1) + ".";
}
if (!user.lastName.isEmpty) {
shortName = shortName + user.lastName.substring(0, 1);
}
return shortName;
}
}
home_presenter.dart
import 'package:flutter_database/database_hepler.dart';
import 'package:flutter_database/User.dart';
import 'dart:async';
abstract class HomeContract {
void screenUpdate();
}
class HomePresenter {
HomeContract _view;
var db = new DatabaseHelper();
HomePresenter(this._view);
delete(User user) {
var db = new DatabaseHelper();
db.deleteUsers(user);
updateScreen();
}
Future<List<User>> getUser() {
return db.getUser();
}
updateScreen() {
_view.screenUpdate();
}
}
homescreen.dart
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_database/add_user_dialog.dart';
import 'package:flutter_database/database_hepler.dart';
import 'package:flutter_database/User.dart';
import 'package:flutter_database/home_presenter.dart';
import 'package:flutter_database/list.dart';
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> implements
HomeContract {
HomePresenter homePresenter;
@override
void initState() {
super.initState();
homePresenter = new HomePresenter(this);
}
displayRecord() {
setState(() {});
}
Widget _buildTitle(BuildContext context) {
var horizontalTitleAlignment =
Platform.isIOS ? CrossAxisAlignment.center :
CrossAxisAlignment.center;
return new InkWell(
child: new Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: horizontalTitleAlignment,
children: <Widget>[
new Text('User Database',
style: new TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
),
);
}
Future _openAddUserDialog() async {
showDialog(
context: context,
builder: (BuildContext context) =>
new AddUserDialog().buildAboutDialog(context, this,
false, null),
);
setState(() {});
}
List<Widget> _buildActions() {
return <Widget>[
new IconButton(
icon: const Icon(
Icons.group_add,
color: Colors.white,
),
onPressed: _openAddUserDialog,
),
];
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: _buildTitle(context),
actions: _buildActions(),
),
body: new FutureBuilder<List<User>>(
future: homePresenter.getUser(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
var data = snapshot.data;
return snapshot.hasData
? new UserList(data,homePresenter)
: new Center(child: new
CircularProgressIndicator());
},
),
);
}
@override
void screenUpdate() {
setState(() {});
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_database/homescreen.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Database',
debugShowCheckedModeBanner: false,
theme: new ThemeData(
primaryColor: const Color(0xFF02BB9F),
primaryColorDark: const Color(0xFF167F67),
accentColor: const Color(0xFFFFAD32),
),
home: new MyHomePage(title: 'Flutter Database'),
);
}
}
PHP MySQL RESTful API
REST (REpresentational State Transfer) adalah suatu arsitektur metode komunikasi
yang sering diterapkan dalam pengembangan layanan berbasis web.
Arsitektur REST, yang umumnya dijalankan via HTTP (Hypertext Transfer
Protocol), melibatkan proses pembacaan laman web tertentu yang memuat sebuah
file XML atau JSON. File inilah yang menguraikan dan memuat konten yang hendak
disajikan. Setelah melalui sebuah proses definisi tertentu, konsumen akan bisa
mengakses antarmuka aplikasi yang dimaksudkan.
Kekhasan REST terletak pada interaksi antara klien dan server yang difasilitasi oleh
sejumlah tipe operasional (verba) dan Universal Resource Identifiers (URIs) yang
unik bagi tiap-tiap sumberdaya. Masing-masing verba – GET, POST, PUT dan
DELETE – memiliki makna operasional khusus untuk menghindari ambiguitas.
REST kerap dipergunakan dalam mobile application, situs web jejaring sosial,
mashup tools, dan automated business processes.
Arsitektur REST yang decoupled (terpisah) serta beban komunikasi yang ringan
antara produsen dan konsumen membuatnya populer di dunia cloud-based API,
seperti yang disajikan oleh Amazon, Microsoft, dan Google.
Layanan berbasis web yang menggunakan arsitektur REST semacam itu dinamakan
RESTful APIs (Application Programming Interfaces) atau REST APIs.
Lab File REST
Buat database dengan nama db_store, kemudia buat table seperti dibawah ini
CREATE TABLE IF NOT EXISTS `tb_item` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_code` text NOT NULL,
`item_name` text NOT NULL,
`price` int(11) NOT NULL,
`stock` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
INSERT INTO `tb_item` (`id`, `item_code`, `item_name`, `price`, `stock`) VALUES
(1, 'B001', 'Kulkas LG 2 Pintu', 1750000, 100),
(2, 'C002', 'Mesin Cuci Sharp', 1250000, 500),
Kemudian buat beberapa file php pada root_directory web server
Conn.php
<?php
$connect = new mysqli("localhost","root","","my_store");
if($connect){
}else{
echo "Connection Failed";
exit();
}
?>
Adddata.php
<?php
include 'conn.php';
$itemcode = $_POST['itemcode'];
$itemname = $_POST['itemname'];
$price = $_POST['price'];
$stock= $_POST['stock'];
$connect->query("INSERT INTO tb_item (item_code,item_name,price,stock) VALUES
('".$itemcode."','".$itemname."','".$price."','".$stock."')")
?>
Deletedata.php
<?php
include 'conn.php';
$id=$_POST['id'];
$connect->query("DELETE FROM tb_item WHERE id=".$id);
?>
Editdata.php
<?php
include 'conn.php';
$id = $_POST['id'];
$itemcode = $_POST['itemcode'];
$itemname = $_POST['itemname'];
$price = $_POST['price'];
$stock= $_POST['stock'];
$connect->query("UPDATE tb_item SET item_code='".$itemcode."',
item_name='".$itemname."', price='".$price."', stock='".$stock."' WHERE id=".
$id);
?>
Getdata.php
<?php
include 'conn.php';
$queryResult=$connect->query("SELECT * FROM tb_item");
$result=array();
while($fetchData=$queryResult->fetch_assoc()){
$result[]=$fetchData;
}
echo json_encode($result);
?>
Kemudian cek apakah REST sudah berjalan dengan baik? Bisa menggunakan
beberapa tools WEB seperti POSTMAN
Lab Flutter – SQL
Main.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import './detail.dart';
import './adddata.dart';
void main() {
runApp(new MaterialApp(
title: "My Store",
home: new Home(),
));
}
class Home extends StatefulWidget {
@override
_HomeState createState() => new _HomeState();
}
class _HomeState extends State<Home> {
Future<List> getData() async {
final response = await
http.get("http://192.168.1.247/rest/getdata.php");
return json.decode(response.body);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("MY STORE"),
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
onPressed: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=> new AddData(),
)
),
),
body: new FutureBuilder<List>(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? new ItemList(
list: snapshot.data,
)
: new Center(
child: new CircularProgressIndicator(),
);
},
),
);
}
}
class ItemList extends StatelessWidget {
final List list;
ItemList({this.list});
@override
Widget build(BuildContext context) {
return new ListView.builder(
itemCount: list == null ? 0 : list.length,
itemBuilder: (context, i) {
return new Container(
padding: const EdgeInsets.all(10.0),
child: new GestureDetector(
onTap: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=> new
Detail(list:list , index: i,)
)
),
child: new Card(
child: new ListTile(
title: new Text(list[i]['item_name']),
leading: new Icon(Icons.widgets),
subtitle: new Text("Stock :
${list[i]['stock']}"),
),
),
),
);
},
);
}
}
adddata.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class AddData extends StatefulWidget {
@override
_AddDataState createState() => new _AddDataState();
}
class _AddDataState extends State<AddData> {
TextEditingController controllerCode = new
TextEditingController();
TextEditingController controllerName = new
TextEditingController();
TextEditingController controllerPrice = new
TextEditingController();
TextEditingController controllerStock = new
TextEditingController();
void addData(){
var url="http://192.168.1.247/rest/adddata.php";
http.post(url, body: {
"itemcode": controllerCode.text,
"itemname": controllerName.text,
"price": controllerPrice.text,
"stock": controllerStock.text
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("ADD DATA"),
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(
children: <Widget>[
new Column(
children: <Widget>[
new TextField(
controller: controllerCode,
decoration: new InputDecoration(
hintText: "Item Code", labelText: "Item
Code"),
),
new TextField(
controller: controllerName,
decoration: new InputDecoration(
hintText: "Item Name", labelText: "Item
Name"),
),
new TextField(
controller: controllerPrice,
decoration: new InputDecoration(
hintText: "Price", labelText: "Price"),
),
new TextField(
controller: controllerStock,
decoration: new InputDecoration(
hintText: "Stock", labelText: "Stock"),
),
new Padding(
padding: const EdgeInsets.all(10.0),
),
new RaisedButton(
child: new Text("ADD DATA"),
color: Colors.blueAccent,
onPressed: () {
addData();
Navigator.pop(context);
},
)
],
),
],
),
),
);
}
}
detail.dart
import 'package:flutter/material.dart';
import './editdata.dart';
import 'package:http/http.dart' as http;
import './main.dart';
class Detail extends StatefulWidget {
List list;
int index;
Detail({this.index,this.list});
@override
_DetailState createState() => new _DetailState();
}
class _DetailState extends State<Detail> {
void deleteData(){
var url="http://192.168.1.247/rest/deleteData.php";
http.post(url, body: {
'id': widget.list[widget.index]['id']
});
}
void confirm (){
AlertDialog alertDialog = new AlertDialog(
content: new Text("Are You sure want to delete
'${widget.list[widget.index]['item_name']}'"),
actions: <Widget>[
new RaisedButton(
child: new Text("OK DELETE!",style: new
TextStyle(color: Colors.black),),
color: Colors.red,
onPressed: (){
deleteData();
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=> new Home(),
)
);
},
),
new RaisedButton(
child: new Text("CANCEL",style: new TextStyle(color:
Colors.black)),
color: Colors.green,
onPressed: ()=> Navigator.pop(context),
),
],
);
showDialog(context: context, child: alertDialog);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new
Text("${widget.list[widget.index]['item_name']}")),
body: new Container(
height: 270.0,
padding: const EdgeInsets.all(20.0),
child: new Card(
child: new Center(
child: new Column(
children: <Widget>[
new Padding(padding: const EdgeInsets.only(top:
30.0),),
new Text(widget.list[widget.index]['item_name'],
style: new TextStyle(fontSize: 20.0),),
new Text("Code :
${widget.list[widget.index]['item_code']}", style: new
TextStyle(fontSize: 18.0),),
new Text("Price :
${widget.list[widget.index]['price']}", style: new
TextStyle(fontSize: 18.0),),
new Text("Stock :
${widget.list[widget.index]['stock']}", style: new
TextStyle(fontSize: 18.0),),
new Padding(padding: const EdgeInsets.only(top:
30.0),),
new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new RaisedButton(
child: new Text("EDIT"),
color: Colors.green,
onPressed: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=>new
EditData(list: widget.list, index: widget.index,),
)
),
),
new RaisedButton(
child: new Text("DELETE"),
color: Colors.red,
onPressed: ()=>confirm(),
),
],
)
],
),
),
),
),
);
}
}
editdata.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import './main.dart';
class EditData extends StatefulWidget {
final List list;
final int index;
EditData({this.list, this.index});
@override
_EditDataState createState() => new _EditDataState();
}
class _EditDataState extends State<EditData> {
TextEditingController controllerCode;
TextEditingController controllerName;
TextEditingController controllerPrice;
TextEditingController controllerStock;
void editData() {
var url="http://192.168.1.247/rest/editdata.php";
http.post(url,body: {
"id": widget.list[widget.index]['id'],
"itemcode": controllerCode.text,
"itemname": controllerName.text,
"price": controllerPrice.text,
"stock": controllerStock.text
});
}
@override
void initState() {
controllerCode= new TextEditingController(text:
widget.list[widget.index]['item_code'] );
controllerName= new TextEditingController(text:
widget.list[widget.index]['item_name'] );
controllerPrice= new TextEditingController(text:
widget.list[widget.index]['price'] );
controllerStock= new TextEditingController(text:
widget.list[widget.index]['stock'] );
super.initState();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("EDIT DATA"),
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(
children: <Widget>[
new Column(
children: <Widget>[
new TextField(
controller: controllerCode,
decoration: new InputDecoration(
hintText: "Item Code", labelText: "Item
Code"),
),
new TextField(
controller: controllerName,
decoration: new InputDecoration(
hintText: "Item Name", labelText: "Item
Name"),
),
new TextField(
controller: controllerPrice,
decoration: new InputDecoration(
hintText: "Price", labelText: "Price"),
),
new TextField(
controller: controllerStock,
decoration: new InputDecoration(
hintText: "Stock", labelText: "Stock"),
),
new Padding(
padding: const EdgeInsets.all(10.0),
),
new RaisedButton(
child: new Text("EDIT DATA"),
color: Colors.blueAccent,
onPressed: () {
editData();
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)=>new
Home()
)
);
},
)
],
),
],
),
),
);
}
}
PDF Viewers
Kita akan coba menggunakan Flutter untuk membuat aplikasi yang dapat
membuka PDF dengan menekan tombol. Pertama kita akan menggunakan paket
Dart untuk menyajikan PDF. Di bawah ini Anda akan melihat langkah-langkah
cara membuka PDF di Flutter dengan flutter_full_pdf_viewer.
1. Setting Dependency (pubscpec.yaml)
dependencies:
flutter_full_pdf_viewer: ^1.0.4
path_provider: ^0.4.1
2. Buat folder assets dan folder pdfs didalamnya, kemudian daftarkan assets
pada file pubspec.yaml
flutter:
assets:
- PDFs/
3. Kemudian jalankan perintah flutter packages get pada CMD
4. Ketik perintah dibawah ini pada file dart anda
5. import 'dart:io';
6. import 'dart:typed_data';
7.
8. import 'package:flutter/material.dart';
9. import 'package:flutter_full_pdf_viewer/full_pdf_viewer_scaffold.dart';
10. import 'package:path_provider/path_provider.dart';
11.
12. // Change this to fit the PDF file you are using to test.
13. const String _documentPath = 'PDFs/Guide-v4.pdf';
14.
15. void main() => runApp(MyApp());
16.
17. class MyApp extends StatelessWidget {
18. @override
19. Widget build(BuildContext context) {
20. return MaterialApp(
21. title: 'Opening a PDF',
22. theme: ThemeData(
23. primarySwatch: Colors.blue,
24. ),
25. home: MyHomePage(),
26. );
27. }
28. }
29.
30. class MyHomePage extends StatefulWidget {
31. MyHomePage({Key key}) : super(key: key);
32.
33. @override
34. _MyHomePageState createState() => _MyHomePageState();
35. }
36.
37. class _MyHomePageState extends State<MyHomePage> {
38. // This moves the PDF file from the assets to a place accessible by our
PDF viewer.
39. Future<String> prepareTestPdf() async {
40. final ByteData bytes =
41. await DefaultAssetBundle.of(context).load(_documentPath);
42. final Uint8List list = bytes.buffer.asUint8List();
43.
44. final tempDir = await getTemporaryDirectory();
45. final tempDocumentPath = '${tempDir.path}/$_documentPath';
46.
47. final file = await File(tempDocumentPath).create(recursive: true);
48. file.writeAsBytesSync(list);
49. return tempDocumentPath;
50. }
51.
52. @override
53. Widget build(BuildContext context) {
54. return Scaffold(
55. appBar: AppBar(
56. title: Text("Opening a PDF"),
57. ),
58. body: Center(
59. child: Column(
60. mainAxisAlignment: MainAxisAlignment.center,
61. children: <Widget>[
62. RaisedButton(
63. onPressed: () {},
64. child: const Text('Open PDF with full_pdf_viewer'),
65. ),
66. ],
67. ),
68. ),
69. );
70. }
71. }
72.
Deploy Signing APK
Setelah selesai membangun aplikasi, langkah selanjutnya adalah membangun
release APK. Adapun langkah – langkahnya seperti berikut :
1. Hilangkan debug mode banner dengan cara :
a. return new MaterialApp(
b. title: 'Flutter Test',
c. debugShowCheckedModeBanner: false, //Seperti ini
d. home: new Column(
e. ...
f. ),
g. builder: (BuildContext context, Widget child) {
h. ...
i. }
j. );
2. Pilih File – Project Structure
3. Pilih Project anda pada module
Click + pada project anda
6. Pada halaman ini, pertama kalian harus membuat file KeyStore berformat .jks.
caranya klik tombol Create new...
7. Isikan data Author dengan lengkap
Berikut keterangan dari data-data yang harus diisi:
Password (Key Store) : Membuat Password key store baru
Alias : Mempunyai peran seperti username, buat nama alias baru
Password (Alias) : Membuat Password Alias baru
Validity (Years) : Isi dengan angka 25 saja
Lalu isi dengan nama lengkap, organisasi unit, nama organisasi, kota, provinsi
dan kode dari negara (Indonesia).
8. Tentukan Path dimana APK akan disimpan (defaultnya ada di
AndroidStudioProjects\<nama_project>\app\build\outputs)