Selamat datang di kutugondrong.com, Anda akan diajarkan untuk membuat aplikasi Flutter sederhana. Jika Anda terbiasa dengan pemrograman berorientasi objek dan konsep dasar pemrograman seperti variabel, loop, dan conditional, Anda akan lebih mudah memahami bahasa pemrograman flutter ini. Anda tidak perlu pengalaman sebelumnya dengan Dart atau pemrograman mobile karena dengan copy paste aplikasi akan jadi lebih mudah. Ikuti tutorial membuat home screen menggunakan bahasa pemrograman flutter ini.
Persiapan pertama :
- Buat sebuah project dengan nama sewain_aku
- Download asset ini. dan simpan setara dengan root package lib.
- kemudian jangan lupa tambahkan config ini di file pubspec.yaml agar asset dikenali.
# To add assets to your application, add an assets section, like this:
assets:
- assets/bmw_6_series/
- assets/honda/
- assets/mercedes_benz_cla/
- assets/porsche/
- Kemudian buat package utils dibawah package lib dan buat file :
- colors.dart
- sizes.dart
- Berikut warna dan default padding yang kita gunakan dalam tutorial membuat home screen menggunakan bahasa pemrograman flutter ini.
code ini copy ke file colors.dart
import 'package:flutter/material.dart';
const primaryColor = Color(0xFF0D55CD);
const textColor = Color(0xFF282A3E);
const backgroundColor = Color(0xFFF9F7FE);
code ini copy ke file sizes.dart
const double defaultPadding = 20.0;
Persiapan Kedua :
- Buat package views dibawah package lib.
- Di dalam package views buat file :
- home_view.dart
- Lalu buat package components dibawah package views.
- Didalam package components ini buat file :
- body.dart
- header_with_search_box.dart
- hot_deals.dart
- title_with_view_all_btn.dart
- top_dealers.dart.
- Didalam package components ini buat file :
- Di dalam package views buat file :
Akhirnya Ini Yang Di tunggu-tunggu
- Update code main.dart
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/views/home_view.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Sewain Aku Donk',
theme: ThemeData(
scaffoldBackgroundColor: primaryColor,
primaryColor: primaryColor,
textTheme: Theme.of(context).textTheme.apply(bodyColor: textColor),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeView(),
);
}
}
- Copy code ini ke home_view.dart
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/views/components/body.dart';
class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: buildAppBar(),
backgroundColor: primaryColor,
body: Body(),
);
}
AppBar buildAppBar() {
return AppBar(
elevation: 0,
leading: IconButton(
onPressed: () {},
icon: Icon(Icons.drag_handle),
),
);
}
}
- Copy code ini ke body.dart
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/utils/sizes.dart';
import 'package:sewain_aku/views/components/hot_deals.dart';
import 'package:sewain_aku/views/components/title_with_view_all_btn.dart';
import 'package:sewain_aku/views/components/top_dealers.dart';
import 'header_with_search_box.dart';
class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
// It will provie us total height and width of our screen
Size size = MediaQuery.of(context).size;
// it enable scrolling on small device
return Container(
child: SingleChildScrollView(
child: Container(
color: backgroundColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
HeaderWithSearchBox(size: size),
TitleWithViewAllBtn(title: "Hot Deals", press: () {}),
HotDeals(),
TitleWithViewAllBtn(title: "Top Dealers", press: () {}),
TopDealers(),
SizedBox(height: defaultPadding),
],
),
),
),
);
}
}
- Copy code ini ke header_with_search_box.dart
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/utils/sizes.dart';
class HeaderWithSearchBox extends StatelessWidget {
const HeaderWithSearchBox({
Key key,
@required this.size,
}) : super(key: key);
final Size size;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: defaultPadding),
height: size.height * 0.2,
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(
left: defaultPadding,
right: defaultPadding,
bottom: 30 + defaultPadding,
),
height: size.height * 0.2 - 27,
decoration: BoxDecoration(
color: primaryColor,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(36),
bottomRight: Radius.circular(36),
),
),
child: Row(
children: <Widget>[
Text(
'Sewain Aku Donk!',
style: Theme.of(context).textTheme.headline5.copyWith(
color: Colors.white, fontWeight: FontWeight.bold),
),
Spacer(),
Icon(Icons.person_pin, color: Colors.white, size: 100,)
],
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.symmetric(horizontal: defaultPadding),
padding: EdgeInsets.symmetric(horizontal: defaultPadding),
height: 54,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
offset: Offset(0, 10),
blurRadius: 50,
color: primaryColor.withOpacity(0.23),
),
],
),
child: Row(
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {},
decoration: InputDecoration(
hintText: "Search",
hintStyle: TextStyle(
color: primaryColor.withOpacity(0.5),
),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
// surffix isn't working properly with SVG
// thats why we use row
// suffixIcon: SvgPicture.asset("assets/icons/search.svg"),
),
),
),
Icon(Icons.search),
],
),
),
),
],
),
);
}
}
- Copy code ini ke hot_deals.dart
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/utils/sizes.dart';
class HotDeals extends StatelessWidget {
const HotDeals({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
HotDealCard(
image: "assets/porsche/porsche_911.png",
title: "Simamora Travel",
location: "Toba Samosir",
price: 200090,
press: () {
},
),
HotDealCard(
image: "assets/porsche/porsche_boxster.png",
title: "Indah Travel",
location: "Dolok Sanggul",
price: 238000,
press: () {
},
),
HotDealCard(
image: "assets/porsche/porsche_cayman.png",
title: "Gondrong Travel",
location: "Medan",
price: 420000,
press: () {},
),
HotDealCard(
image: "assets/porsche/porsche_macan.png",
title: "Kutu Gondrong",
location: "Jakarta",
price: 340000,
press: () {},
),
],
),
);
}
}
class HotDealCard extends StatelessWidget {
const HotDealCard({
Key key,
this.image,
this.title,
this.location,
this.price,
this.press,
}) : super(key: key);
final String image, title, location;
final int price;
final Function press;
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final double widthCard = size.width * 0.6;
return Container(
margin: EdgeInsets.only(
left: defaultPadding,
top: defaultPadding / 2,
bottom: defaultPadding * 2.5,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
width: widthCard,
child: GestureDetector(
onTap: press,
child: Column(
children: <Widget>[
Container(
alignment: Alignment.topLeft,
padding: new EdgeInsets.only(left: defaultPadding, top: defaultPadding),
child: Text("$title",
style: Theme.of(context)
.textTheme
.button
.copyWith(color: textColor),
),
),
Container(
alignment: Alignment.topLeft,
padding: new EdgeInsets.only(left: defaultPadding),
child: Text(
"$location",
style: Theme.of(context)
.textTheme
.button
.copyWith(color: primaryColor.withOpacity(0.5)),
),
),
Image.asset(image),
Container(
width: widthCard,
alignment: Alignment.centerRight,
padding: new EdgeInsets.only(right: defaultPadding, bottom: defaultPadding/2),
child: Text(
'Rp $price',
style: Theme.of(context)
.textTheme
.button
.copyWith(color: primaryColor),
),
),
SizedBox(
width: widthCard,
child: FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
),
color: primaryColor,
onPressed: () {},
child: Text(
"Rent Now",
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
),
],
),
),
);
}
}
- Copy code ini ke title_with_view_all_btn.dart
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/utils/sizes.dart';
class TitleWithViewAllBtn extends StatelessWidget {
const TitleWithViewAllBtn({
Key key,
this.title,
this.press,
}) : super(key: key);
final String title;
final Function press;
@override
Widget build(BuildContext context) {
return Container(
child: Container(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: defaultPadding),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: defaultPadding / 4),
child: Text(
title,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
Spacer(),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
color: primaryColor,
onPressed: press,
child: Text(
"View All",
style: TextStyle(color: Colors.white),
),
),
],
),
),
),
);
}
}
- Copy code ini ke top_dealers.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:sewain_aku/utils/colors.dart';
import 'package:sewain_aku/utils/sizes.dart';
class TopDealers extends StatelessWidget {
const TopDealers({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
TopDealersCard(
image: "assets/mercedes_benz_cla/exterior_l_2.png",
title: "Mercedes Benz",
press: () {},
),
TopDealersCard(
image: "assets/porsche/porsche_911.png",
title: "Porsche",
press: () {},
),
TopDealersCard(
image: "assets/bmw_6_series/exterior_l_4.png",
title: "BMW 6 Series",
press: () {},
),
TopDealersCard(
image: "assets/honda/honda_civic.png",
title: "Honda",
press: () {},
),
],
),
);
}
}
class TopDealersCard extends StatelessWidget {
const TopDealersCard({
Key key,
this.image,
this.title,
this.press,
}) : super(key: key);
final String image;
final String title;
final Function press;
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
margin: EdgeInsets.only(
left: defaultPadding,
top: defaultPadding / 2,
bottom: defaultPadding * 2.5,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(defaultPadding)),
),
child: GestureDetector(
onTap: press,
child: Container(
child: Column(
children: [
Container(
margin: EdgeInsets.only(
left: defaultPadding,
top: defaultPadding / 2,
),
width: size.width * 0.8,
height: 185,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage(image),
),
),
),
Padding(
padding: const EdgeInsets.all(defaultPadding/2),
child: Text(
"$title",
style: TextStyle(
color: textColor,
fontSize: 26,
fontWeight: FontWeight.bold
),
),
),
],
),
),
),
);
}
}