Hi π, bersama saya Arif Iskandar. Nah kali ini kita akan melakukan slicing aplikasi Bookies dengan menggunakan Flutter. Oh iya, Bookies adalah aplikasi mobile untuk membaca buku digital.
Jadi, ayo kita mulai.
- Persiapan
- Membuat Projek
- Menyiapkan assets dan dependencies
- Membuat Struktur Projek
- Theme
- Membuat Model Data
- Menyiapkan Data
- Coding TIme
Aplikasi yang digunakan:
- Figma
- Visual Studio Code
- Emulator
- Windows - Android Studio Emulator atau
- Mac - Xcode Simulator atau
- IPhone / Android
Apabila semua aplikasi sudah disiapkan, pastikan kamu telah menginstall flutter di laptop / pc kamu.
Download file figmanya di Shaynakit.com.
- Buka Aplikasi Visual Studio Code
- Untuk membuat projek silahkan tekan
CTRL + P
atauCommand + P
di Visual Studio Code. Kemudian ketikkan>Flutter: New Project
lalu tekanEnter
- Kemudian pilih
Application
- Lalu pilih lokasi folder projek yang ingin di buat, dan terakhir ketikkan
bookies
pada pilihan nama projek. - Tunggu sampai proses selesai, maka akan terbentuk struktur projek seperti gambar ini.
Buka file figma yang telah di download kemudian export semua gambar kedalam folder /assets/images/
.
βββ ...
βββ android
βββ assets/
β βββ images/
β βββ 1.png
β βββ 2.png
β βββ 3.png
βββ ios
βββ ...
Selanjutnya, kita akan mendaftarkan gambar-gambar tadi kedalam pubspec.yaml
# pubspec.yaml
# ...
flutter:
# ...
assets:
- assets/images/
# ...
Setelah assets ditambahkan kita juga akan menginstall Feather Icons
untuk semua icon yang kita gunakan pada projek kali ini.
# pubspec.yaml
# ...
dependencies:
# ...
flutter_feather_icons: ^2.0.0
# ...
Kemudian simpan pubspec.yaml
dan lakukan Flutter Doctor
agar assets dan dependencies kita dapat dipakai.
Caranya dengan menekan CTRL + P
atau Command + P
ketikkan >Flutter: Run Flutter Doctor
lalu tekan Enter
.
Pada tahap ini kita akan membuat folder untuk projek kita, biasanya ada beberapa folder di dalam folder lib
yang harus di buat seperti components
, datas
, models
, screens
, dan juga theme.dark
untuk menyimpan theme kita.
.
βββ ...
βββ ios
βββ lib/
β βββ components/
β βββ datas/
β βββ models/
β βββ screens/
β βββ main.dart
β βββ theme.dart
βββ linux
βββ ...
Setelah kita amati dan perhatikan file figma terdapat beberapa warna dan jenis tulisan yang dipakai, itu semua akan kita masukkan ke dalam theme.dart
agar dapat kita pakai secara berulang-ulang.
-
Warna
Warna Kode Warna text #35325E
textSecondary #90909E
blue #8EC9F5
purple #ADAEFF
red #FDEBEA
gray #F6F8FA
// theme.dart import 'package:flutter/material.dart'; // Colors Color text = const Color(0XFF35325E); Color textSecondary = const Color(0XFF90909E); Color blue = const Color(0XFF8EC9F5); Color purple = const Color(0XFFADAEFF); Color red = const Color(0XFFFDEBEA); Color gray = const Color(0XFFF6F8FA);
-
Typography
Untuk typography sendiri biasanya kalau saya tidak memakai design system, saya akan mengelompokkan berdasarkan jenis dan besar tulisan. Untuk menghemat file size dan merapikan code kita, saya akan mengcopy dan mengubah fontSize dari yang sudah ada.
// theme.dart // ... // Typography TextStyle regular10 = const TextStyle(fontSize: 10); TextStyle regular14 = regular10.copyWith(fontSize: 10); TextStyle medium14 = const TextStyle(fontSize: 14, fontWeight: FontWeight.w500); TextStyle medium16 = medium14.copyWith(fontSize: 16); TextStyle medium18 = medium14.copyWith(fontSize: 18);
-
Topic
// lib/models/topic.dart import 'package:flutter/material.dart'; class Topic { final IconData icon; final Color color; final String title; final int totalBook; Topic(this.icon, this.color, this.title, this.totalBook); }
-
Book
// lib/models/book.dart class Book { final String title; final String image; final String topic; Book(this.title, this.image, this.topic); }
Setelah model disiapkan, kita akan menyiapkan data yang akan digunakan pada aplikasi ini. Data dapat diambil dari desain yang ada di figma sebagai contoh, namun untuk data yang real bisa diambil dari database maupun api.
// lib/datas/topics.dart
import 'package:bookies/models/topic.dart';
import 'package:bookies/theme.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
List<Topic> topics = [
Topic(
FeatherIcons.award, // icon
blue, // color
'My Self Improvement', // title
84 // totalBook
),
Topic(
FeatherIcons.trendingUp,
purple,
'Business Education',
12
),
Topic(
FeatherIcons.star,
red,
'Non-Fiction Stories',
5
),
];
// lib/datas/populars.dart
import 'package:bookies/models/book.dart';
List<Book> populars = [
Book(
"Lamp of Brightnes Real World", // title
"assets/images/1.png", // image
"Growth Business" // topic
),
Book(
"Art of Gathering Do Meeting",
"assets/images/2.png",
"Team Product"
),
Book(
"Tiger In The Garden For Eating",
"assets/images/3.png",
"Children Story"
)
];
Kita akan membuat file home_page.dart
didalam folder screens sebagai tempat kita berimajinasi hehehe. Kemudian buat Stateless Widget
sebagai pondasi utamanya.
// lib/screens/home_page.dart
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container();
}
}
Selanjutnya ubah main.dart
agar dapat terhubung dengan home_page.dart
.
import 'package:flutter/material.dart';
import 'package:bookies/screens/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(), // menjadikan home sebagai screen pertama yang akan dibuka
);
}
}
Karena kita halaman bisa di scroll maka kita akan menggunakan SingleChildScrollView
dan Column
untuk menampung semua komponennya
// libs/screen/home_page.dart
//...
// Containernya kita ganti Scaffold
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(
// agar elemen di dalamnya rata kiri
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Views akan di letakkan di bagian ini
],
)
),
);
//...
Kita akan membuat tulisan Topics
dengan style medium 18
dengan padding atas 40, kiri 24, dan bawah 12
// libs/screen/home_page.dart
// ...
Column(
//...
children: [
// Tulisan Topics
Padding(
padding: const EdgeInsets.only(top: 40, left: 24, bottom: 12),
child: Text(
'Topics',
style: medium18.copyWith(color: text),
),
)
],
)
// ...
Kemudian kita membuat horizontal scroll untuk daftar topik yang tersedia, karena memiliki ukuran yang sama jadi kita pakai ListView.separated
agar rapi. Dan kita akan membungkus listview dengan SizedBox
dengan ukuran seperti yang ada di gambar
// Tulisan Topics
SizedBox(
height: 180,
child:
ListView.separated(
// membuat list horizontal
scrollDirection: Axis.horizontal,
// padding list ke kiri dan kanan
padding: const EdgeInsets.symmetric(horizontal: 24),
// Dibagian ini akan kita ganti dengan komponen TopicItem yang akan dibuat
itemBuilder: ((context, index) => Container()),
// Jarak antara komponen
separatorBuilder: (context, index) => const SizedBox(width: 16,),
// jumlah komponen
itemCount: topics.length
),
)
Kita akan membuat komponen untuk topic diddalam folder components
dan menghubungkannya dengan ListView
// lib/components/topic_item.dart
import 'package:bookies/models/topic.dart';
import 'package:flutter/material.dart';
class TopicItem extends StatelessWidget {
// topic yang akan dikirim dari ListView
final Topic topic;
const TopicItem({Key? key, required this.topic}) : super(key: key);
@override
Widget build(BuildContext context) {
// Layout untuk Topik disini
return Container();
}
}
// lib/screens/home_page.dart
// ...
ListView.separated(
itemBuilder:
((context, index) =>
TopicItem(topic: topics[index])
),
)
Tahap terakhir adalah membuat layout untuk topik sesuai dengan ukuran yang ada di desain.
// lib/components/topic_item.dart
// ...
return Container(
// Ukuran container
width: 138,
height: 180,
padding: const EdgeInsets.all(18),
// kita membuat warna container dan juga border radius
decoration: BoxDecoration(
color: topic.color,
borderRadius: BorderRadius.circular(25)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Untuk lingkaran luar Icon
Container(
padding: const EdgeInsets.all(11),
decoration: BoxDecoration(
color: Colors.white.withOpacity(.6),
borderRadius: BorderRadius.circular(23)),
child: Icon(
topic.icon,
color: text,
size: 24,
),
),
// Pemisah
const Spacer(),
// Judul topic
Text(
topic.title,
style: medium14.copyWith(color: text),
),
const SizedBox(height: 6,),
// Jumblah buku
Text('${topic.totalBook} books',
style: regular10.copyWith(
color: text.withOpacity(.7)
),
)
],
),
);
// ...
Hasil nya, yeayyy
Kita akan membuat judul Most popular
seperti judul yang sebelumnya
// lib/screens/home_page.dart
// ...
// ListView.separated
// Tulisan Most Popular
Padding(
padding: const EdgeInsets.only(top: 32, left: 24, bottom: 12),
child: Text(
'Most Popular',
style: medium18.copyWith(color: text),
),
)
// ...
Kemudian kita akan melakukan perulangan untuk semua buku populer
// ...
// Tulisan Most Pupular
...populars.map(
(book) => PopularItem(book: book) // komponen popular item
)
// ...
Kita akan membuat komponen PopularItem
didalam folder components
// lib/components/popular_item.dart
import 'package:bookies/models/book.dart';
import 'package:flutter/material.dart';
class PopularItem extends StatelessWidget {
// book yang akan dikirim dari list
final Book book;
const PopularItem({Key? key, required this.book}) : super(key: key);
@override
Widget build(BuildContext context) {
// Layout untuk Buku disini
return Container();
}
}
Tahap terakhir adalah membuat layout untuk buku pupuler sesuai dengan ukuran yang ada di desain.
// lib/components/popular_item.dart
return Container(
// conainer terluar
padding: const EdgeInsets.only(left: 24, bottom: 12, right: 24),
height: 178,
child: Container(
padding: const EdgeInsets.only(
left: 16, top: 16,
bottom: 16, right: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: const Color(0xFFF6F8FA)),
child: Row(
children: [
// Gambar buku
Container(
clipBehavior: Clip.hardEdge,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(13)),
child: Image.asset(book.image),
),
const SizedBox(
width: 16,
),
// Judul dan topik
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Judul
Text(
book.title,
style: medium16.copyWith(color: text),
),
const SizedBox(
height: 8,
),
// Topik
Text(
book.topic,
style: regular14.copyWith(color: textSecondary),
),
],
)),
// Icon
SizedBox(
width: 36,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(18),
color: Colors.white),
child: const Icon(
FeatherIcons.heart,
size: 16,
),
)
],
),
)
],
),
),
);
Hasil nya, yeayyy
No | Plugin |
---|---|
1. | Awsome Flutter Snippets |
2. | Dart |
3. | Flutter |
4. | Rainbow Brackets |