Terakhir diperbarui: 18 September 2022

Penulis: Tim Pengajar Mobile Flutter

Pada codelab ini, Anda akan mempelajari tentang fungsi transform widget, Matrix4, dan jenis-jenis transformasi.

Tujuan Praktikum

Setelah menyelesaikan codelab ini Anda akan mampu untuk:

Tujuan Visual

Sumber Daya yang Dibutuhkan

Berikut merupakan sumber daya yang diperlukan untuk menyelesaikan praktikum ini:

Daftar Perintah

Tida ada.

Bantuan

Tidak ada.

Pengetahuan yang Anda harus Miliki

Kita telah melihat banyak widget di pertemuan sebelumnya, tetapi terkadang kita mungkin perlu mengubah tampilan widget untuk meningkatkan UX. Melakukan respon terhadap input user atau untuk membuat efek keren dalam tata letak, kita mungkin perlu memindahkan widget di sekitar layar, mengubah ukurannya, atau bahkan sedikit mengubahnya.

Jika Anda pernah mencoba dalam bahasa pemrograman native, Anda mungkin merasa kesulitan. Flutter, seperti yang disebutkan sebelumnya, sangat fokus pada desain UI dan bertujuan untuk membuat hidup developer lebih mudah dengan menyederhanakan apa yang bisa dengan mudah pada area yang rumit.

Di bagian ini, pertama-tama kita akan melihat widget Transform karena ini adalah widget yang sangat berguna saat Anda melakukan manipulasi widget. Kemudian akan mempelajari lebih dalam widget untuk melihat jenis-jenis manipulasi yang mungkin bisa dilakukan.

Transform widget

Widget Transform adalah salah satu contoh terbaik dari kekuatan dan konsistensi framework Flutter. Ini adalah widget tujuan tunggal yang hanya menerapkan transformasi grafis ke anaknya, dan tidak lebih. Memfokuskan widget pada satu tujuan adalah dasar untuk struktur tata letak yang lebih baik, dan Flutter melakukannya dengan sangat baik.

Widget Transform, seperti namanya, melakukan satu tugas—itu mengubah turunan dasarnya. Meskipun tugasnya sangat kompleks, ia menyembunyikan sebagian besar kerumitan ini dari pengembang. Mari kita lihat kodenya sebagai berikut:

const Transform({
  Key,
  required Matrix4 transform,
  Offset origin, AlignmentGeometry alignment,
  bool transformHitTests: true,
  Widget child
})

Seperti yang Anda lihat, selain properti Key, widget ini tidak memerlukan banyak argumen untuk melakukan tugasnya. Mari kita lihat penjelasan parameter masing-masing sebagai berikut:

Transformasi Matrix4 sangat penting untuk kelas Transform, jadi mari kita lihat lebih detail.

Memahami Matrix4 class

Di Flutter, transformasi direpresentasikan sebagai matriks 4D. Meskipun terdengar sangat menakutkan, matriks 4D hanyalah matriks yang memiliki empat baris dan empat kolom, seperti yang ditunjukkan di sini:

Nilai matriks yang ditampilkan adalah matriks identitas. Ini adalah nilai khusus karena secara efektif mengatakan untuk tidak melakukan perubahan dalam transformasi. Saat nilai dalam matriks diubah, maka widget ditransformasikan dengan cara yang berbeda.

Seringkali, kita tidak perlu mengetahui nilai spesifik dari matriks untuk melakukan transformasi.

Selain metode seperti penambahan atau perkalian matriks, kelas Matrix4 berisi metode yang membantu konstruksi dan manipulasi transformasi geometris. Beberapa di antaranya tercantum di sini:

Mari kita lihat bagaimana kita dapat menggunakan kelas Matrix4 untuk memberlakukan berbagai jenis transformasi.

Explorasi jenis-jenis transformasi

Kelas Transform menyediakan fasilitas kepada pengembang melalui konstruktor pabriknya.

Ada banyak dari mereka untuk setiap kemungkinan transformasi, sehingga sangat mudah untuk menerapkan transformasi ke widget tanpa pengetahuan yang lebih dalam tentang perhitungan geometris. Terdiri dari:

Mari kita lihat masing-masing jenis transformasi secara lebih rinci.

Rotate transformation

Transformasi putar muncul dalam situasi di mana kita hanya ingin membuat widget kita berputar. Dengan menggunakan konstruktor Transform.rotate(), kita bisa mendapatkan widget yang diputar.

Itu tidak terlalu berbeda dari konstruktor Transform default. Perbedaannya tercantum di sini:

Kita dapat menggunakannya seperti ini:

Transform.rotate(
  angle: -45 * (math.pi / 180.0),
  child: ElevatedButton(
    child: Text("Rotated button"),
    onPressed: () {},
  ),
);

Pada contoh ini, kita spesifikkan sudut radian yang digunakan (misalnya sudut 315° searah jarum jam sama dengan sudut -45° berlawanan), dan widget child akan berotasi, dalam contoh ini yaitu widget ELevatedButton.

Hasil yang sama persis akan diperoleh ketika menggunakan widget Transform dan Matrix4, seperti yang diilustrasikan pada kode berikut:

Transform(
  transform: Matrix4.rotationZ(-45 * (pi / 180.0)),
  alignment: Alignment.center,
  child: ElevatedButton (
    child: Text("Rotated button"),
    onPressed: () {},
  ),
);

Argumen yang perlu kita berikan untuk mendapatkan hasil yang sama adalah properti transform dengan rotasi melalui sumbu z, dan properti alignment dari transformasi yang menentukan pusat child widget.

Scale transformation

Transformasi skala muncul dalam situasi di mana kita hanya ingin membuat widget kita mengubah ukurannya, baik dengan menambah atau mengurangi skalanya. Sama seperti konstruktor pabrik rotate() , varian ini tidak terlalu berbeda dari yang default. Berikut adalah beberapa rincian lebih lanjut mengenai hal ini:

Misalnya, untuk memperbesar widget, kita dapat menjalankan kode berikut:

Transform.scale(
    scale: 2.0,
    child: ElevatedButton(
    child: Text("scaled up"),
    onPressed: () {},
    ),
);

Di sini, kami telah menetapkan properti skala 2.0, yang menggandakan ukuran widget anak, dan sekali lagi menetapkan bahwa widget anak adalah ElevatedButton. Jelas, Anda bisa mengatur ukuran ElevatedButton untuk menghindari transformasi.

Dan untuk mendapatkan hasil yang sama dengan menggunakan konstruktor Transform default, kami menggunakan kode berikut:

Transform(
  transform: Matrix4.identity()..scale(2.0, 2.0),
  alignment: Alignment.center,
  child: ElevatedButton(
    child: Text("scaled up"),
    onPressed: () {},
  ),
);

Dengan cara yang sangat mirip dengan rotasi, kita harus menentukan asal transformasi dengan properti keselarasan dan instance Matrix4 yang menjelaskan transformasi skala.

Translate transformation

Transformasi terjemahan kemungkinan akan muncul dalam animasi, seperti yang dijelaskan nanti dalam bab di bagian Menggunakan animasi.

Di sini, kami memiliki lebih sedikit properti dibandingkan dengan transformasi sebelumnya.

Perbedaannya tercantum sebagai berikut:

Dengan menggunakan konstruktor Transform.translate(), kita memindahkan widget di sekitar layar, dengan menambahkan widget Transform sebagai induk dari widget yang ingin kita pindahkan, seperti yang diilustrasikan dalam cuplikan kode berikut:

Transform.translate(
  offset: Offset(100, 300),
  child: ElevatedButton(
    child: Text("translated to bottom"),
    onPressed: () {},
  ),
);

Konstruktor default juga dapat digunakan dengan Matrix4 yang menentukan terjemahan, sebagai berikut:

Transform(
  transform: Matrix4.translationValues(100, 300, 0),
  child: ElevatedButton(
    child: Text("translated to bottom"),
    onPressed: () {},
  ),
);

Kita hanya perlu menentukan properti transform dengan instance Matrix4 yang menjelaskan terjemahannya.

Composed transformations

Kita dapat—dan kemungkinan besar akan—menggabungkan sejumlah transformasi yang terlihat sebelumnya untuk mencapai efek unik, seperti memutar pada saat yang sama saat kita memindahkan dan menskalakan widget.

Menyusun transformasi dapat dilakukan dengan dua cara, sebagai berikut:

Untuk lebih jelasnya, mari kita lihat bagaimana kita akan menyarangkan beberapa widget Transform, sebagai berikut:

Transform.translate(
  offset: Offset(70, 200),
  child: Transform.rotate(
    angle: -45 * (math.pi / 180.0),
    child: Transform.scale(
      scale: 2.0,
      child: ElevatedButton(
        child: Text("multiple transformations"),
        onPressed: () {},
        ),
     ),
   ),
);

Seperti yang Anda lihat, kami menambahkan widget Transform sebagai turunan ke widget Transform lainnya, yang menyusun transformasi. Meskipun lebih sederhana untuk dibaca, metode ini memiliki kelemahan:

kami menambahkan lebih banyak widget daripada yang dibutuhkan ke pohon widget.

Saat kita menambahkan beberapa transformasi ke widget secara bersamaan, kita harus memperhatikan urutan transformasi. Bereksperimen sendiri: menukar posisi widget Transform akan menghasilkan hasil yang berbeda.

Sebagai alternatif, kita dapat menggunakan konstruktor Transform default dengan transformasi tersusun dengan objek Matrix4, sebagai berikut:

Transform(
  alignment: Alignment.center,
  transform: Matrix4.translationValues(70, 200, 0)
    ..rotateZ(-45 * (math.pi / 180.0))
    ..scale(2.0, 2.0),
  child: ElevatedButton(
    child: Text("multiple transformations"),
    onPressed: () {},
  ),
);

Sama seperti sebelumnya, kami menentukan perataan transformasi sebagai pusat widget anak dan kemudian instance Matrix4 untuk menggambarkannya. Seperti yang Anda lihat, ini sangat mirip dengan beberapa versi widget Transform tetapi tanpa widget bersarang, menyebabkan pohon widget yang lebih dalam.

Sekarang kita telah menjelajahi cara memanipulasi widget dengan cara statis, mari kita lihat membuat animasi pada pertemuan berikutnya untuk memungkinkan widget berpindah dari satu keadaan ke keadaan lain dengan cara yang lebih halus.

Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau Android Studio atau code editor lain kesukaan Anda.

Langkah 1: Buat Project Baru

Buatlah sebuah project flutter baru dengan nama flutter_transform. Lalu jadikan repository di GitHub Anda dengan nama flutter_transform.

Langkah 2: Impor dart:math

Tambahkan library dart:math pada file main.dart

import 'dart:math';

Langkah 3: Tambahkan kode Transform

Tetap di file main.dart di class _MyHomePageState pada bagian widget build, letakkan kode berikut di dalam children: setelah teks $_counter.

Transform.rotate(
    angle: -45 * (pi / 180.0),
    child: ElevatedButton(
      child: const Text("Rotated button"),
      onPressed: () {},
    ),
),
            Transform(
              transform: Matrix4.rotationZ(-45 * (pi / 180.0)),
              alignment: Alignment.center,
              child: ElevatedButton(
                child: const Text("Rotated button"),
                onPressed: () {},
              ),
            ),
            Transform.scale(
              scale: 2.0,
              child: ElevatedButton(
                child: const Text("scaled up"),
                onPressed: () {},
              ),
            ),
            Transform(
              transform: Matrix4.identity()..scale(2.0, 2.0),
              alignment: Alignment.center,
              child: ElevatedButton(
                child: const Text("scaled up (matrix)"),
                onPressed: () {},
              ),
            ),
            Transform.translate(
              offset: const Offset(100, 300),
              child: ElevatedButton(
                child: const Text("translated to bottom"),
                onPressed: () {},
              ),
            ),
            Transform(
              transform: Matrix4.translationValues(100, 300, 0),
              child: ElevatedButton(
                child: const Text("translated to bottom (matrix)"),
                onPressed: () {},
              ),
            ),
            Transform.translate(
              offset: const Offset(70, 200),
              child: Transform.rotate(
                angle: -45 * (pi / 180.0),
                child: Transform.scale(
                  scale: 2.0,
                  child: ElevatedButton(
                    child: const Text("multiple transformations"),
                    onPressed: () {},
                  ),
                ),
              ),
            ),
            Transform(
              alignment: Alignment.center,
              transform: Matrix4.translationValues(70, 200, 0)
                ..rotateZ(-45 * (pi / 180.0))
                ..scale(2.0, 2.0),
              child: ElevatedButton(
                child: const Text("multiple transformations (matrix)"),
                onPressed: () {},
              ),
            )

Run aplikasi tersebut dengan tekan F5, maka hasilnya akan seperti berikut.

  1. Selesaikan Praktikum tersebut, lalu dokumentasikan dan push ke repository Anda berupa screenshot hasil pekerjaan beserta penjelasannya di file README.md!
  2. Tetap di project yang sama, buatlah folder dan file dart baru lalu praktikkan kode yang ada di tautan ini terkait perspektif di flutter!
  3. Tetap di project yang sama, buatlah folder dan file dart baru lalu praktikkan kode yang ada di tautan ini untuk membuat flip animasi 3D!
  4. Kumpulkan laporan praktikum Anda berupa link repository GitHub ke LMS!

Selamat Anda telah menyelesaikan Codelab ini. Anda telah mempelajari terkait manipulasi widget dengan class Transform.

Pada codelab berikutnya, Anda akan mempelajari tentang Animasi.

Apa selanjutnya?

Silakan cek beberapa sumber belajar lainnya...

Referensi