Stateful widget is a widget that can change when a user interacts with it, whereas a stateless widget never changes. Icon, IconButton, and Text are examples of stateless widgets.
Padding
: Adds padding or empty space around a widget or a bunch of widgets.Row
: Aligns children horizontally.Visibility
: Sets children visible or not.FloatingActionButton
: A circular icon button that hovers over content to promote a primary action in the application.Text
: Displays a string of text.
setState()
function is to notify the framework that the internal state of this object has changed which causes the framework to schedule a build for this State object. The variables that are affected by setState()
depends on what variable you pass inside the setState()
function.
Both are immutable but you can't use const
for a value that is compiled at runtime, so if you want to use const
you must know the value at compile time, ex: const a = 1
. Therefor, final
should be used over const
if you don't know the value at compile time, and it will be calculated/grabbed at runtime.
- Run
flutter create counter_7
- Edit
lib/main.dart
:-
Create decreament counter function:
void _decrementCounter() { setState(() { if (_counter > 0) { _counter--; } }); }
-
Add logic to GANJIL-GENAP text:
children: <Widget>[ _counter % 2 == 0 ? const Text('GENAP', style: TextStyle(color: Colors.redAccent)) : const Text('GANJIL', style: TextStyle(color: Colors.blueAccent)), Text( '$_counter', style: Theme.of(context).textTheme.headline4, ), ],
-
Modify
floatingActionButton
:floatingActionButton: Padding( padding: const EdgeInsets.only(left: 30), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Visibility( visible: _counter != 0, child: FloatingActionButton( onPressed: _decrementCounter, tooltip: 'Decrement', backgroundColor: _counter == 0 ? Colors.grey : Colors.blueAccent, child: const Icon(Icons.remove), ) ), FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ], )) // This trailing comma makes auto-formatting nicer for build
-
git
add
-commit
-push
Assignment
-
Navigator.push
pushes the route into the stack on top of the current page, thereby displaying the second route. Meanwhile, Navigator.pushReplacement
replaces the current page with the route you want to push.
DropdownButton
: Lets the user select from a number of items.DropdownHideUnderline
: Removes Underline fromDropdownButton
.TextButton
: It is a simple Button without any border that listens for onPressed and onLongPress gestures.ListView.builder
: Builds the children on demand. This constructor is appropriate for list views with a large (or infinite) number of children.ListTile
: Used to populate a ListView in Flutter. It contains title as well as leading or trailing icons.Material
: A convenience widget that wraps a number of widgets that are commonly required for applications implementing Material Design.
onPressed
: This callback will be called when the user taps on an object.onTap
: Called when the user taps on the render object.onChanged
: Called when the user initiates a change to the TextField's or other fields' value.
When we navigate to another screen, we use the push
methods and Navigator
widget adds the new screen onto the top of the stack. Naturally, the pop
methods would remove that screen from the stack.
- Make
drawer.dart
that containsDrawerApp
that will be used as main's, data_budget's and tambah_budget's drawer to navigate pages.drawer: const DrawerApp(),
- Make a form that accepts
String judul
,int nominal
,String jenisBudget
anddate
as the inputs intambah_budget.dart
. - Make a
Budget
class intambah_budget.dart
that accepts the same inputs as the form.class Budget { late String judul; late int nominal; late String jenisBudget; late DateTime date; Budget({ required this.judul, required this.nominal, required this.jenisBudget, required this.date }); }
- Make
globals.dart
that contains global variablebudgets
which is a list ofBudget
.// globals.dart library counter_7.globals; import 'package:counter_7/tambah_budget.dart'; List<Budget> budgets = [];
- Show the data in
globals.budgets
indata_budget.dart
usingListView.builder
that containsListTile
. - Decorate.
Can we fetch a JSON data without making a model first? If yes, is it better than making a model first?
Yes, we can fetch a JSON data without making a model first. We can make a dynamic map from the JSON and access the value like a dictionary in python (data[key]
). But it is not recommended as we wouldn't know if there is a missing field or the fields is not what we expect, so I'll be hard to manage and error-prone. That being said, it is obvious that it's not better than making a model first.
ListTile
: Used to populate a ListView in Flutter. It contains title as well as leading or trailing icons.Checkbox
: Used to make a clickable checkbox.TextButton
: It is a simple Button without any border that listens for onPressed and onLongPress gestures.FutureBuilder
: Widget that builds itself based on the latest snapshot of interaction with a Future.
Data is fetched using HTTP in fetchWatchlist
function that call the get function by HTTP instances. The function returns the list of MyWatchlist
object. FutureBuilder
will call the function and wait for its response. When the data is fetched, FutureBuilder
returns ListView.builder
that builds ListTiles
containing the mapped data that we get from fetchWatchlist
function.
- Create
mywatchlist.dart
and make aMyWatchlist
class. - Create
fetch_watchlist.dart
and make a function like this to fetch data from the API.// fetch_watchlist.dart Future<List<MyWatchlist>> fetchWatchlist() async { var url = Uri.parse('https://edutjie-pbp-2.herokuapp.com/mywatchlist/json/'); var response = await http.get( url, headers: { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json", }, ); // melakukan decode response menjadi bentuk json var data = jsonDecode(utf8.decode(response.bodyBytes)); // melakukan konversi data json menjadi object MyWatchlist List<MyWatchlist> listMyWatchlist = []; for (var d in data) { if (d != null) { listMyWatchlist.add(MyWatchlist.fromJson(d)); } } return listMyWatchlist; }
- Create
my_watchlist.dart
and make aMyWatchlistPage StatefulWidget
that containsFutureBuilder
that fetch data usingfetchWatchlist
function. - Create
my_watchlist_detail.dart
and make aMyWatchlistDetailPage StatelessWidget
that displays the data that is going to be pass fromMyWatchlistPage
. - Pass data from
MyWatchlistPage
toMyWatchlistDetailPage
usingNavigator.push
.Navigator.push( context, MaterialPageRoute( builder: (context) => MyWatchlistDetailPage( movie: snapshot.data![index], ), ));
- Create
CheckBox
widget and itsonChanged
function for Bonus.Checkbox( activeColor: Colors.limeAccent, checkColor: Colors.black, focusColor: Colors.lightGreenAccent, value: snapshot.data![index].fields.watched, onChanged: (bool? value) { setState(() { snapshot.data![index].fields.watched = value!; }); }, )