Transaksi Activity pada Aplikasi dengan Flutter

Bagikan jika Anda sukai postingan ini!

 Aplikasi Transaksi Activity
Aplikasi Transaksi Activity

Pembahasan kali ini saya akan mencoba menjelaskan bagaimana cara memanggil/menampilkan activity lain dari activity utama. Silakan memulai proyek baru dengan Flutter, atau Anda dapat meneruskan proyek yang sudah pernah dibuat pada artikel ini.

Saya akan menggunakan 3 (tiga) activity pada pembahasan kali ini. Ketiga activity ini akan saya simpan pada berkas dart baru. Untuk menambahkan berkas dart baru, lihat panel Project Anda.

Panel Project Flutter pada Android Studio
Panel Project Flutter pada Android Studio

Berkas-berkas dart akan disimpan pada alamat <nama-proyek>\lib. Untuk menambahkan berkas dart baru, klik kanan pada cabang lib. Pada menu pop-up yang ditampilkan, sorot menu New kemudian klik menu File. Kita akan menambahkan 3 (tiga) buah berkas baru yaitu: people.dart, second.dart, dan third.dart. Mari kita mulai dengan people.dart. Ketikkan people.dart pada dialog New File yang ditampilkan.

Ubah kode sumber people.dart seperti di bawah ini.

class PeopleItem {
  String name;
  int age;

  PeopleItem({this.name, this.age});
}

Pada people.dart kita membuat sebuah kelas dengan nama PeopleItem untuk menampung informasi yang akan ditransaksikan antar activity.

Kemudian tambahkan berkas dart lainnya. Kita lanjutkan dengan third.dart lebih dulu. Ubah kode sumber third.dart seperti di bawah ini.

import 'package:flutter/material.dart';
import 'people.dart';

class ThirdActivity extends StatefulWidget {
  /* Variable statis */
  final PeopleItem people;

  /* Konstrutor baru untuk ThirdActivity */
  const ThirdActivity({Key key, @required this.people}) : super(key: key);

  @override
  ThirdPage createState() {
    return ThirdPage();
  }
}

class ThirdPage extends State<ThirdActivity>{
  TextEditingController _ageController;
  PeopleItem _people;

  /* initState: Inisialisasi awal */
  @override
  void initState() {
    _ageController = new TextEditingController();
    /* Mengisi variable _people dari widget.people
       widget.people adalah variabel yang menyertai
       saat ThirdActivity dipanggil
    */
    _people = widget.people;

    /* Mengisi text pada TextField dengan nilai variabel _people.age
     hanya jika nilai _people.age di atas 0 */
    if (_people.age > 0) _ageController.text = _people.age.toString();
    super.initState();
  }

  /* setPeople:
     - Mengubah dan menyimpan nilai ariabel _people.age
     - Menutup ThirdActivity sembari mengirim variabel _people
  */
  void setPeople(){
    /* Mengubah dan menyimpan nilai variabel _people.age */
    setState(() {
      String age = _ageController.text;
      /* Jika text pada TextField kosong maka ubah jadi 0 */
      if (age.isEmpty) age = '0';

      _people.age = int.parse(age);
    });

    /* Menutup ThirdActivity sembari mengirim variabel _people */
    Navigator.pop(context, _people);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Insert Age"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.symmetric(
                  horizontal: 16.0, vertical: 4.0),
              child: Row(
                children: <Widget>[
                  Text("Name"),
                  SizedBox(width: 50.0,),
                  Text(_people.name,
                    style: TextStyle(
                      fontWeight: FontWeight.bold)
                    ,
                  ),
                ],
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(
                  horizontal: 16.0, vertical: 4.0),
              child: Row(
                children: <Widget>[
                  Text("Age"),
                  SizedBox(width: 50.0,),
                  Flexible(
                    child: TextField(
                      controller: _ageController,
                      keyboardType: TextInputType.number,
                    ),
                  ),
                ],
              ),
            ),
            RaisedButton(
              color: Colors.blue,
              onPressed: setPeople,
              child: Text("Next",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 14.0,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Kode sumber pada third.dart ini merupakan activity ke-3 pada aplikasi yang kita kembangkan ini.

Lanjutkan dengan membuat berkas second.dart, kemudian ubah kode sumbernya menjadi seperti di bawah ini.

import 'package:flutter/material.dart';
import 'people.dart';
import 'third.dart';

class SecondActivity extends StatefulWidget {
  final PeopleItem people;
  const SecondActivity({Key key, this.people}) : super(key: key);

  @override
  SecondPage createState() {
    return SecondPage();
  }
}

class SecondPage extends State<SecondActivity>{
  TextEditingController _nameController;
  PeopleItem _people;

  /* initState: Inisialisasi awal */
  @override
  void initState() {
    _nameController = new TextEditingController();
    /* Mengisi variable _people dari widget.people
       widget.people adalah variabel yang menyertai
       saat SecondActivity dipanggil
    */
    _people = widget.people;

    /* Mengisi text pada TextField dengan nilai variabel _people.name */
    _nameController.text = _people.name;
    super.initState();
  }

  /* setPeople:
     - Mengubah dan menyimpan nilai ariabel _people.name
     - Memanggil ThirdActivity sembari mengirim informasi pada variabel _people
     - Menutup SecondActivity sembari mengirim variabel _people
  */
  void setPeople(){
    /* Mengubah dan menyimpan nilai variabel _people.name */
    setState(() {
      _people.name = _nameController.text;
    });

    /* Memanggil ThirdActivity sembari mengirim
    informasi pada variabel _people  */
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => ThirdActivity(people: _people),
      ),
    ).then((value){
      /* Ketika menerima data dari Navigator */
      /* Mengubah dan menyimpan variabel _people */
      setState(() {
        _people = value;
      });

      /* Menutup SecondActivity sembari mengirim variabel _people */
      Navigator.pop(context, value);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Insert Name"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.symmetric(
                  horizontal: 16.0, vertical: 4.0),
              child: Row(
                children: <Widget>[
                  Text("Name"),
                  SizedBox(width: 50.0,),
                  Flexible(
                    child: TextField(
                      controller: _nameController,
                      keyboardType: TextInputType.text,
                    ),
                  ),
                ],
              ),
            ),
            RaisedButton(
              color: Colors.blue,
              onPressed: setPeople,
              child: Text("Next",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 14.0,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Selanjutnya, modifikasi berkas main.dart menjadi seperti di bawah ini.

import 'package:flutter/material.dart';
import 'people.dart';
import 'second.dart';

void main(){
  runApp(MainApp());
}

class MainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MainActivity(),
    );
  }
}

class MainActivity extends StatefulWidget {
  @override
  MainPage createState() {
    return MainPage();
  }
}

class MainPage extends State<MainActivity>{
  PeopleItem _people;

  /* initState: Inisialisasi awal */
  @override
  void initState() {
    _people = new PeopleItem(name: '', age: 0);
    super.initState();
  }

  /* setPeople: Memanggil SecondActivity sembari
     mengirim informasi pada variabel _people
  */
  void setPeople(){
    /* Memanggil SecondActivity */
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => SecondActivity(people: _people),
      ),
    ).then((value){
      /* Ketika menerima data dari Navigator */
      if (value != null){
        /* Mengubah dan menyimpan variabel _people */
        setState(() {
          _people = value;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My First App"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.symmetric(
                  horizontal: 16.0, vertical: 4.0),
              child: Row(
                children: <Widget>[
                  Text("Name"),
                  SizedBox(width: 50.0,),
                  Text(_people.name,
                    style: TextStyle(
                      fontWeight: FontWeight.bold
                    ),
                  ),
                ],
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(
                  horizontal: 16.0, vertical: 4.0),
              child: Row(
                children: <Widget>[
                  Text("Age"),
                  SizedBox(width: 50.0,),
                  Text(_people.age.toString(),
                    style: TextStyle(
                      fontWeight: FontWeight.bold
                    ),
                  ),
                ],
              ),
            ),
            RaisedButton(
              color: Colors.blue,
              onPressed: setPeople,
              child: Text("Edit",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 14.0,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Simpan pekerjaan Anda, kemudian coba jalankan aplikasi pada emulator atau perangkat terhubung Anda.

Pertama kali dijalankan, aplikasi akan menampilkan activity dengan informasi Name (kosong) dan Age 0, serta sebuah tombol Edit.

Activity Utama Aplikasi
Activity Utama Aplikasi

Klik tombol Edit, maka akan ditampilkan activity ke-2. Ketikkan sebuah nama pada kotak Name kemudian klik tombol Next. Maka akan ditampilkan activity ke-3.

Activity Kedua Aplikasi
Activity Kedua Aplikasi

Pada activity ke-3 akan ditampilkan informasi Name sesuai dengan nilai yang Anda masukkan pada activity sebelumnya. Activity ke-3 akan meminta Anda memasukkan nilai Age. Silakan masukkan angka kemudian klik tombol Next.

Activity Ketiga Aplikasi
Activity Ketiga Aplikasi

Setelah memasukkan Age pada activity ke-3, aplikasi akan kembali ke activity utama, tapi kali ini dengan menampilkan informasi yang sudah Anda masukkan pada kedua activity sebelumnya.

Activity Utama Aplikasi dengan Informasi
Activity Utama Aplikasi dengan Informasi

Mari kita bahas kode sumbernya. Kita mulai dari kode sumber pada third.dart. Pada bagian awal dari berkas third.dart, Anda dapat melihat perintah untuk mengimpor berkas people.dart. Ya, untuk dapat menggunakan kode sumber dari berkas dart lainnya, Anda harus melakukan perintah import lebih dulu pada bagian paling atas kode sumber.

import 'people.dart';

Selanjutnya, pada third.dart terdapat 2 (dua) buah kelas yang dideklarasikan yaitu ThirdActivity dan ThirdPage. Tidak jauh berbeda dengan yang sudah dibahas pada artikel sebelumnya. Hanya saja kali ini pada kelas ThirdActivity yang merupakan turunan kelas StatefulWidget saya menambahkan sebuah variabel statis bernama people dan deklarasi kosntruktor baru untuk kelas ThirdActivity.

  /* Variable statis */
  final PeopleItem people;

  /* Konstrutor baru untuk ThirdActivity */
  const ThirdActivity({Key key, this.people}) : super(key: key);

Pada konstruktor baru, saya tambahkan argumen people untuk menampung data bertipe PeopleItem yang nantinya akan dibawa serta saay kelas ThirdActivity dipanggil dari kelas lain.

Anda bisa saja mengubah kosntruktor menjadi seperti di bawah ini.

const ThirdActivity({Key key, @required this.people}) : super(key: key);

Ketika Anda menambahkan @required sebelum nama argumen, maka nilai argumen tersebut wajib diisi saat pemanggilan kelas.

ThirdActivity(people: _people);
new ThirdActivity(people: _people);

Anda juga bisa saja menambahkan lebih dari satu argumen pada kosntruktor.

  /* Variable statis */
  final PeopleItem people;
  final OtherItem other;

  /* Konstrutor baru untuk ThirdActivity */
  const ThirdActivity({Key key, @required this.people, this.other}) : super(key: key);

Selanjutnya pada bagian deklarasi kelas ThirdPage. Saya menambahkan variabel _ageController bertipe TextEditingController dan variabel _people bertipe PeopleItem. Variabel _ageController digunakan untuk mengontrol widget TextField (dengan mengeset argumen controller pada suatu TextField), seperti untuk mengubah dan mengambil nilai text dari TextField. Variabel _people saya gunakan untuk memroses variabel people yang diterima dari Navigator dan kemudian dikirim kembali ke Navigator.

  TextEditingController _ageController;
  PeopleItem _people;

Pada kelas ThirdPage terdapat metode bentukan dari kelas State, yaitu initState. Metode initState digunakan untuk menginisialisasi awal variabel atau metode yang akan digunakan pada kelas ThirdPage. Pada metode tersebut saya menginisialisasi variabel _ageController, mengisi variabel _people dengan widget.people (variabel yang diterima ThirdActivity dari Navigator), serta mengubah atribut text dari _ageController dengan nilai _people.age.

  /* initState: Inisialisasi awal */
  @override
  void initState() {
    _ageController = new TextEditingController();
    /* Mengisi variable _people dari widget.people
       widget.people adalah variabel yang menyertai
       saat ThirdActivity dipanggil
    */
    _people = widget.people;

    /* Mengisi text pada TextField dengan nilai variabel _people.age
     hanya jika nilai _people.age di atas 0 */
    if (_people.age > 0) _ageController.text = _people.age.toString();
    super.initState();
  }

variabel dengan nama yang diawali dengan garis bawah (underscore) menandakan bahwa jangkauan variabel tersebut bersifat private, artinya variabel tersebut tidak dapat diakses dari kelas lain.

Catatan

Pada kelas ThirdPage saya membuat sebuah metode yang bernama setPeople. Metode ini akan dipanggil saat tombol Next diklik. Metode ini saya gunakan untuk mengubah dan menyimpan nilai variabel _people.age yang diambil dari _ageController.text, juga untuk menutup activity.

  /* setPeople:
     - Mengubah dan menyimpan nilai ariabel _people.age
     - Menutup ThirdActivity sembari mengirim variabel _people
  */
  void setPeople(){
    /* Mengubah dan menyimpan nilai variabel _people.age */
    setState(() {
      String age = _ageController.text;
      /* Jika text pada TextField kosong maka ubah jadi 0 */
      if (age.isEmpty) age = '0';

      _people.age = int.parse(age);
    });

    /* Menutup ThirdActivity sembari mengirim variabel _people */
    Navigator.pop(context, _people);
  }

Sedangkan untuk layout dari activity ThirdActivity dapat Anda simak pada metode/fungsi build dari kelas ThirdPage. Anda dapat menemukan penggunaan kelas TextField dengan nilai argumen controller-nya saya set ke _ageController, serta kelas RaisedButton dengan nilai argumen onPressed-nya saya set ke setPeople.

Saat menggunakan TextField sebagai widget anak dari Row, pastikan TextField ditampung oleh widget Flexible, karena jika tidak, maka akan terjadi kesalahan (error) saat pemuatan layout.

Catatan

Kita beralih ke kode sumber berkas second.dart. Kode sumber pada second.dart tidak jauh berbeda dengan kode sumber third.dart. Perbedaan paling terlihat pada metode setPeople di kelas SecondPage. Di sana saya menambahkan perintah untuk memanggil/menampilkan ThirdActivity sebelum SecondActivity di tutup.

  /* setPeople:
     - Mengubah dan menyimpan nilai ariabel _people.name
     - Memanggil ThirdActivity sembari mengirim informasi pada variabel _people
     - Menutup SecondActivity sembari mengirim variabel _people
  */
  void setPeople(){
    /* Mengubah dan menyimpan nilai variabel _people.name */
    setState(() {
      _people.name = _nameController.text;
    });

    /* Memanggil ThirdActivity sembari mengirim
    informasi pada variabel _people  */
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => ThirdActivity(people: _people),
      ),
    ).then((value){
      /* Ketika menerima data dari Navigator */
      /* Mengubah dan menyimpan variabel _people */
      setState(() {
        _people = value;
      });

      /* Menutup SecondActivity sembari mengirim variabel _people */
      Navigator.pop(context, value);
    });
  }

Untuk memanggil activity lain seperti ThirdActivity, Anda cukup menggunakan perintah seperti di bawah ini.

    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => ThirdActivity(people: _people),
      ),
    );

Namun karena saya mengharapkan nilai kembali setelah activity (ThirdActivity) ditutup, maka saya memanfaatkan fungsi then dari Navigator.

then((value){
  //Perintah-perintah
})

Selanjutnya kode sumber dari main.dart, ini juga tidak jauh berbeda dengan kode sumber berkas dart lainnya dan sepertinya tidak membutuhkan penjelasan. Hanya saja saya “menormalisasi” kode sumber dengan menambahkan deklarasi kelas turunan dari StatelessWidget sebelum ditampilkan sebagai activity utama.

class MainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MainActivity(),
    );
  }
}

Kemudian,

void main(){
  runApp(MainApp());
}

Itu saja yang dapat saya sampaikan untuk pembahasan kali ini. Pembahasan selanjutnya kita akan mencoba cara menyimpan nilai pengaturan pada perangkat, sehingga saat aplikasi dijalankan di lain waktu, maka nilai pengaturan ini akan digunakan.