In this tutorial, you will learn to create your app with Flutter, which can help you calculate tips (when you buy chips, ha-ha). In this process, you will explore a few interesting things from the Flutter stack: What is a ? widget What method does? build - one of the most exciting features of Flutter Hot Reload Ready? Let’s start! A Little Theory is an entity, which can have some state. Also, this entity is a way to declare and construct the UI of your app. As the Flutter team says: Widget All is Widget The Widget can be small and plain - only one word in the text can be a separated Widget. But, on the other hand, Widget can be huge with much complex logic. Well, to start, you need to have installed Flutter and Dart. I hope you have done this. Next - create a Flutter application from the template with the command: flutter create. The 'tip app' will consist of only one screen - in which you can see two simple text fields - one for the overall amount of your order and the second input for the tip percentage. The screen also has two text lines with a tip in dollars and a total amount of charge, which equals the overall amount + tip amount. Source Code ; ; ; ; ; ; ; ; ; ; ; ; ; ; { OrderView({ Key? key, }) : (key: key); _OrderViewState createState() => _OrderViewState(); } { late OrderState orderState; initState() { .initState(); orderState = OrderState() ..registerHook(() { setState(() {}); }) ..initState(); } dispose() { orderState.dispose(); .dispose(); } Widget build(BuildContext context) { infoStyle = TextStyl.bold(context); Padding( padding: EdgeInsets.all(Pad.l1), child: Column( children: [ TextFormField( decoration: InputDec.outline8.copyWith( labelText: Locale.billTotalLabel, ), keyboardType: TextInputType.number, controller: orderState.billTotalController, inputFormatters: [ NumberFormatter(), ], ), VDivider(), TextFormField( decoration: InputDec.outline8.copyWith( labelText: Locale.tipPercentLabel, ), keyboardType: TextInputType.number, controller: orderState.tipAmountController, inputFormatters: [ NumberFormatter( : ), ], ), VDivider(level: DividerLevel.l2), Row( children: [ Text( Locale.tipAmountTitle, style: infoStyle, ), AnimatedText( Utils.formatMoney(orderState.order.tipAmount), style: infoStyle.copyWith(fontWeight: FontWeight.bold), useOpacity: , ), ], ), VDivider(), MoneyRow( title: Locale.totalAmountTitle, money: orderState.order.totalWithTipAmount, ), Expanded( child: Center( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(Locale.changeTipHint, style: TextStyl.bold(context)), Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: Icon(Icons.add), onPressed: orderState.increaseTip, color: Colors.green, highlightColor: Colors.transparent, splashColor: Colors.green.withOpacity( ), ), HDivider(), IconButton( icon: Icon(Icons.remove), onPressed: orderState.reduceTip, color: Colors.red, highlightColor: Colors.transparent, splashColor: Colors.red.withOpacity( ), ), ], ), VDivider(level: DividerLevel.l5), ], ), ), ) ], ), ); } } import 'package:anitex/anitex.dart' import 'package:flutter/material.dart' import 'package:flutter/services.dart' import 'package:flutter/widgets.dart' import 'package:tipsalc/order/view/money_row.dart' import '../../constants/input.dart' import '../../constants/padding.dart' import '../../constants/text_style.dart' import '../../locale/locale.dart' import '../../utils/formatters.dart' import '../../utils/utils.dart' import '../../widgets_helpers/horizontal_divider.dart' import '../../widgets_helpers/vertical_divider.dart' import '../state/order.state.dart' class OrderView extends StatefulWidget const super @override < > class _OrderViewState extends State OrderView will /// We use Flutter 2.0 with Dart 2.12 you /// which offer null-safety @override void super will /// For state management we /// use simple [setState] method /// But to prevent placing business logic will /// in UI layer - we take out it in /// separate class [OrderState] @override void super @override final return const /// This is first field with just /// amount of order will /// We using formatter /// for prevent input non-digit symbols /// in our input const /// Second field with amount of tips /// in percents int true const /// This is two ours text lines with /// total amount of tips in dollars false const the /// And second row with total amount just /// of all order ( order + tips in dollars) a /// Well, there we have visual helper to manipulate you /// tips quantity - can simple increase or reduce the /// amount of tips with step in 5% const 0.15 const const 0.15 const StatefulWidget From this sample, you can see that we use a for our single screen because it has its own state, where you can place some data which you can rule. We place the data in a separate class, StatefulWidget OrderState. The logic is placed there too, but the UI layer's renewal is with - state of - , which can refresh UI by calling method. _OrderViewState OrderView StatefulWidget setState initState() { .initState(); orderState = OrderState() ..registerHook(() { setState(() {}); }) ..initState(); } @override void super will /// For state management we /// use simple [setState] method /// But to prevent placing business logic will /// in UI layer - we take out it in /// separate class [OrderState] /// We pass method [setState] to our /// OrdersState class, where this method will /// called after any data updates StatelessWidget The second type of that you can see in this example is a . In opposite to - that type hasn’t its own state - the only UI without and logic. But you also can use methods and data, which you must pass to your from its parents. Widget StatelessWidget StatefulWidget StatelessWidget For example, our widget places two identical widgets with the same goal - show the user two similar rows with text. Here they are: OrderView Row( children: [ Text( Locale.tipAmountTitle, style: infoStyle, ), AnimatedText( Utils.formatMoney(orderState.order.tipAmount), style: infoStyle.copyWith(fontWeight: FontWeight.bold), useOpacity: , ), ], ), false You can also simplify the code as follows: MoneyRow( title: Locale.tipAmountTitle, money: orderState.order.tipAmount, ), You create your own . StatelessWidget ; ; ; ; { MoneyRow({ required .title, required .money, Key? key, }) : (key: key); title; money; Widget build(BuildContext context) { infoStyle = TextStyl.bold(context); Row( children: [ Text( title, style: infoStyle, ), AnimatedText( Utils.formatMoney(money), style: infoStyle.copyWith(fontWeight: FontWeight.bold), useOpacity: , ), ], ); } } import 'package:anitex/anitex.dart' import 'package:flutter/widgets.dart' import '../../constants/text_style.dart' import '../../utils/utils.dart' class MoneyRow extends StatelessWidget const this this super final String final num /// We move all UI logic from /// old place (OrderView) to here you /// and in OrderView can use simple /// and small widget MoneyRow instead /// this several widgets /// you /// And also can reuse this in any place your /// of app @override final return false Build Method As you can see - we moved widgets from to separate widget . However, we placed them in a special method , which must return a widget too. What does this mean? All Widgets must have a build method and that will be called by the parent of the widget. As Flutter docs say: OrderView MoneyRow build Build method describes the part of the user interface represented by this widget. The framework calls this method when the widget is inserted into the tree in a given and when the dependencies of this widget change (e.g., an referenced by this widget changes). This method can potentially be called in every frame and should not have any side effects beyond building a widget. BuildContext InheritedWidget Super Exciting Hot Reload Hot Reload. How nice to hear these words! That feature saves your time as a developer time. You can ask - How Well - because you can change the code and see the result of your actions simultaneously. You can change the theme of all your app, and after part of one second - you will see your app in new colors. You can cut a big part of your widgets and replace them with another and see changes after splits of seconds. But you must know that you can make some changes and don’t see any difference in-app. ? For example - you add new logic in some method which called only once when your app loading or in method - in that situations, you must using feature - it is like Hot Reload, but it reloads all Flutter layer of your app without saving of state. So in some situations, you must use Hot Restart instead of Hot Reload. You will understand when to use what. initState the Hot Restart Conclusion To start creating apps with Flutter you should know how widgets work. You can use in small applications for simple state management. You can also use to separate complex UI logic into simple different widgets, from which you will assemble the interface like a constructor. StatefulWidgets StatelessWidgets You can see this application in real-time . here