flutter memungkinkan kita untuk membuat aplikasi yang ... · flutter adalah teknologi untuk...

74
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.

Upload: others

Post on 18-May-2020

45 views

Category:

Documents


0 download

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

2. Pilih Start a new Flutter Project

3. Pilih Flutter Application

4. Beri nama project, tentukan Flutter SDK yang sudah dipersiapkan

sebelumnya

5. Tentukan nama domain, biasanya diberi nama perusahaan (TIDAK

DISARANKAN MENGGUNAKAN DOMAIN EXAMPLE.COM)

6. Wizard sudah selesai, dan Android Studio akan masuk ke tampilan utama

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:

15, color:Colors.black)

)

],

)

),

);

},

)

);

}

}

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

4. Pilih Android

5. Kemudian pilih Build – Generate Signed APK

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)