Tugas 12 - Pemrograman Perangkat Bergerak
Hesekiel Nainggolan
5025201054
PPB I
FRAMEWORK FLUTTER 1 - NAMER
Halo, pada pertemuan kali ini, kita akan membahas mengenai framework flutter. Flutter adalah toolkit UI Google untuk membangun aplikasi untuk perangkat seluler, web, dan desktop dari codebase tunggal. Untuk implementasi kali ini, kita akan membuat aplikasi Namer. Aplikasi ini menghasilkan nama yang terkesan keren, seperti "newstay", "lightstream", "mainbrake", atau "graypine". Pengguna dapat meminta nama berikutnya, memfavoritkan nama saat ini, dan meninjau daftar nama yang difavoritkan di halaman terpisah. Aplikasi ini responsif terhadap berbagai ukuran layar:
Sebelum kita melakukan pembuatan aplikasinya, pertama sekali kita harus menyiapkan beberapa tools yang diperlukan:
- Visual Studio Code
- Android Studio
- Visual Studio
- Instalasi SDK flutter yang digunakan
Untuk detail dari instalasi nya dapat menonton melalui halaman link Youtobe. Selanjutnya, kita akan mulai membuat aplikasinya:
1. Membuat proyek Flutter pertama Anda
Buka Visual Studio Code dan buka palet perintah (dengan Ctrl+Shift+P atau Shift+Cmd+P). Kemudian ketik "flutter new" dan pilih perintah Flutter: New Project. Berikutnya, pilih Application lalu folder tempat proyek akan dibuat. Folder ini dapat berupa direktori utama Anda, atau direktori seperti C:\src\. Terakhir, beri nama proyek Anda. Beri nama seperti namer_app atau my_awesome_namer.
2. Membuat Aplikasi
Selanjutnya ialah membuat aplikasi. Kita dapat mengambil kode nya dari Github. Dalam proses pembuatanya memerlukan beberapa langkah:
- Menyalin Code Awal
Ada beberapa code yang harus dipersiapkan diawal:
pubspec.yaml.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: namer_app | |
description: A new Flutter project. | |
publish_to: 'none' # Remove this line if you wish to publish to pub.dev | |
version: 0.0.1+1 | |
environment: | |
sdk: '>=2.19.4 <4.0.0' | |
dependencies: | |
flutter: | |
sdk: flutter | |
english_words: ^4.0.0 | |
provider: ^6.0.0 | |
dev_dependencies: | |
flutter_test: | |
sdk: flutter | |
flutter_lints: ^2.0.0 | |
flutter: | |
uses-material-design: true |
analysis_options.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include: package:flutter_lints/flutter.yaml | |
linter: | |
rules: | |
prefer_const_constructors: false | |
prefer_final_fields: false | |
use_key_in_widget_constructors: false | |
prefer_const_literals_to_create_immutables: false | |
prefer_const_constructors_in_immutables: false | |
avoid_print: false |
lib/main.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:english_words/english_words.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:provider/provider.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return ChangeNotifierProvider( | |
create: (context) => MyAppState(), | |
child: MaterialApp( | |
title: 'Namer App', | |
theme: ThemeData( | |
useMaterial3: true, | |
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange), | |
), | |
home: MyHomePage(), | |
), | |
); | |
} | |
} | |
class MyAppState extends ChangeNotifier { | |
var current = WordPair.random(); | |
void getNext() { | |
current = WordPair.random(); | |
notifyListeners(); | |
} | |
var favorites = <WordPair>[]; | |
void toggleFavorite() { | |
if (favorites.contains(current)) { | |
favorites.remove(current); | |
} else { | |
favorites.add(current); | |
} | |
notifyListeners(); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
@override | |
State<MyHomePage> createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
var selectedIndex = 0; | |
@override | |
Widget build(BuildContext context) { | |
Widget page; | |
switch (selectedIndex) { | |
case 0: | |
page = GeneratorPage(); | |
case 1: | |
page = FavoritesPage(); | |
default: | |
throw UnimplementedError('no widget for $selectedIndex'); | |
} | |
return LayoutBuilder(builder: (context, constraints) { | |
return Scaffold( | |
body: Row( | |
children: [ | |
SafeArea( | |
child: NavigationRail( | |
extended: constraints.maxWidth >= 600, | |
destinations: [ | |
NavigationRailDestination( | |
icon: Icon(Icons.home), | |
label: Text('Home'), | |
), | |
NavigationRailDestination( | |
icon: Icon(Icons.favorite), | |
label: Text('Favorites'), | |
), | |
], | |
selectedIndex: selectedIndex, | |
onDestinationSelected: (value) { | |
setState(() { | |
selectedIndex = value; | |
}); | |
}, | |
), | |
), | |
Expanded( | |
child: Container( | |
color: Theme.of(context).colorScheme.primaryContainer, | |
child: page, | |
), | |
), | |
], | |
), | |
); | |
}); | |
} | |
} | |
class GeneratorPage extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
var appState = context.watch<MyAppState>(); | |
var pair = appState.current; | |
IconData icon; | |
if (appState.favorites.contains(pair)) { | |
icon = Icons.favorite; | |
} else { | |
icon = Icons.favorite_border; | |
} | |
return Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
BigCard(pair: pair), | |
SizedBox(height: 10), | |
Row( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
ElevatedButton.icon( | |
onPressed: () { | |
appState.toggleFavorite(); | |
}, | |
icon: Icon(icon), | |
label: Text('Like'), | |
), | |
SizedBox(width: 10), | |
ElevatedButton( | |
onPressed: () { | |
appState.getNext(); | |
}, | |
child: Text('Next'), | |
), | |
], | |
), | |
], | |
), | |
); | |
} | |
} | |
class BigCard extends StatelessWidget { | |
const BigCard({ | |
super.key, | |
required this.pair, | |
}); | |
final WordPair pair; | |
@override | |
Widget build(BuildContext context) { | |
final theme = Theme.of(context); | |
final style = theme.textTheme.displayMedium!.copyWith( | |
color: theme.colorScheme.onPrimary, | |
); | |
return Card( | |
color: theme.colorScheme.primary, | |
child: Padding( | |
padding: const EdgeInsets.all(20), | |
child: Text( | |
pair.asLowerCase, | |
style: style, | |
semanticsLabel: "${pair.first} ${pair.second}", | |
), | |
), | |
); | |
} | |
} | |
class FavoritesPage extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
var appState = context.watch<MyAppState>(); | |
if (appState.favorites.isEmpty) { | |
return Center( | |
child: Text('No favorites yet.'), | |
); | |
} | |
return ListView( | |
children: [ | |
Padding( | |
padding: const EdgeInsets.all(20), | |
child: Text('You have ' | |
'${appState.favorites.length} favorites:'), | |
), | |
for (var pair in appState.favorites) | |
ListTile( | |
leading: Icon(Icons.favorite), | |
title: Text(pair.asLowerCase), | |
), | |
], | |
); | |
} | |
} |
Hasil :
Komentar
Posting Komentar