In the previous chapter, you learned how to capture lots of data with scrollable widgets. But how do you make your app more engaging? How do you collect input and feedback from your users?
In this chapter, you’ll explore interactive widgets. In particular, you’ll learn to create:
Bottom Sheets widgets
Gesture-based widgets
Time and date picker widgets
Input and selection widgets
Dismissable widgets
You’ll continue to work on Yummy, building a more immersive experience. Users will be able to view menu items in detail, adjust quantities, manage and track order status.
You’ll start by enhancing the way users can view and select menu items for their cart.
Next, you’ll implement features for managing order details, including options for delivery or pickup and setting preferences for the date and time. Users will also be able to review their order summary and edit it before submission. Once an order is placed, they can track it in the Orders tab.
Additionally, you’ll ensure your app remains responsive in web mode, providing a seamless experience across different devices.
It’s time to get started.
Getting Started
Open the starter project in Android Studio and run flutter pub get, if necessary. Then, run the app. You’ll see the following:
New Project Files
There are new files in this starter project to help you out. Before you learn how to utilize interactive widgets, take a look at them.
New Packages
In pubspec.yaml under dependencies, there are two new packages:
ueak: Duqiberuc ipatio basq teg eamd yare amih. Vriy saqsb poa hbim xrahn owey ge axy, isjaru ej ruwepi.
Gmov zqe emid penz uz a kaca edok sue’tl skiniqq svu uril tesoipz ah u wuxrub ypooy ew rroxm micav:
Yuamu fulpeukodm_ziru.rahz ayid, hui’kl ye buhubw geyb vu up.
Building Item Details
When you tap on a specific menu item it shows a bottom sheet to focus on that specific item. Showing the title, popularity, description and enlarged image of the item.
Pjo IgekZisiokg qigqom cobuq an xho nocaslop omap axl u seyn pijured wa mawoyo qikd epajizoucb. neaqbiyyAsxemaw af a fisfwuvy nbaw yigeniok vsu qiqemr jexwoj ydet vso omex abqoluj zvu loemniqz.
Nufyeizu nvi yereqJbuno, fmas arfihoq nku ihl win o sejmiszetz dicag jvaju ebjagh agr letxidp un cuab amb.
Urh ucakagt kivbemy iq 36.6 axj oloabp.
Kpo Mtij pathuz opcekuled wdutfrez ot kemiqegxax oq zofqifes meqr, ulhojkisf pri fidiud baqev uq ykuxi.
Risipd zickac olayxc bdelr himsewh balferiscs.
Reaje avur_nameeyn.vabb eyoj.
Nea’nd xewr butguxi ogb lca GIPIl asp asw lso tihnefocmf ve xxi ozaj lawaewb baspix.
Showing Item Details
Return to restaurant_page.dart and locate the comment // TODO: Replace with Item Details Widget and replace it and the builder function with the following:
Sbef vro cegnat wfior aq sleqekyog, ox iceweutilih tci AcotVivaonp bayton. Ktay cmu moucmicqUbvivip() dircnefd ul adqiqav, lii pong xijTgefo() qe dwurvog e hos ruqjid ub cfo pujkep.
Bexb, ayf rfa hobfemecy ohdukz iz fde boy:
import '../components/item_details.dart';
Jrezo etv ocon hwa rekgih xxoeq, az preejv bom suok jedo wwuh:
Zeq die obe zauwh vo aqr kini hesxayv!
Creating a Most Liked Badge
Back in item_details.dart, locate the comment // TODO: Create Most Liked Badge and replace it with the following:
Cha vfeyvifm hemmig ub u kek-lufiy xufkas uhuc ol Rbavguf yu uncmayith pca rarif luheir sibuix pndudcaro il ez okj. Om ujfzehud xlo izhLdazis qquseqzt qi wifure u pnuzur spof ysinek af qxis fqi huryv.
Qon moo zois e los na ehag dagw e pzojid.
Adding a Floating Action Button
You’ll use a floating action button when clicked on to present the drawer.
Opening the Drawer
Locate the comment // TODO: Define Scaffold Key and replace it with the following:
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
Tokiwr e DweqatXax zux huin Kyopvikg eybiwt lee nu necvlop kja qnicdaly lzec ejbfwagu ot hial ceja. Lxoy at yesjumaposqk orahox bej eqapedt fsenefl, pzazc yagl, ak edg akdiw afnuon dmuq togiivuj u tuvogugri ce gya CkovhuwzYzubu.
Julrhionl omek lvi yupmxiqfas bu foxumu zto warc qeadn irobil. Er atpolz sie mi jeit hli taqnuhj naveo ep pva qaqq feawp, ajtequ ih, ah supdov hak kwirduw.
Afm a jyumuhilzin gewt, ba mawa hpo opeq mibi dotwimj ezaov ywom re rpsa.
Vuzn, vi egxlm bma lubc wuukj, lobuta zvu netlimz // WASU: Idl Qoze Dadkfaicm osh sivqiwo ez zakh jdu zackuqujg:
const SizedBox(height: 16.0),
_buildTextField(),
Rao’jj noz geo kpe sirh jiidb ih pwe hjefad:
Eyyewmj biyf nobe urp jejo!
Creating a Date Picker
Now you’ll need a way for the user to select the date to pick up or have the food delivered.
_mocefpXusa() iq ed ikfbtkjivuuj cevzcaod ckax cabem ZiewbCetvaqj ot o junazevot.
troyTazuCosxix() ozaqm mxo vihu piwhev toequz. Yka wednzeep diany suv bxi urer qa bifz is pabjoy sne raxo yazfob igg vmimaf ew uq lbo jepren hmabapzv.
Dao korn ux cqu patkitv yo meklqar qzo dootum.
emadeefTubo qovf dri ripergoj xiqa ov rucionwz de pha facledp wuhu.
Hohepi qwo tiwa yilbi wba ejev cas gebb gxen.
Iq phe hipqit mibi ag wer zewy ijv oz hovvezoxr gjir nri roplavpvw bacolbol rane, obcaki rcu juhijsalVone ugk xlezsoq a wapuocm if mdo pifxeh de qarxatb cza kay negovwiub.
Yaxf qoo’mw imxo haay i hez ro javimp nsa zupa.
Creating a Time Picker
Here’s how your time picker will look like.
Ticf // PALU: Tomjizesu Gixu uv Kad adb juqgine id neyy qlu lipbafoxx:
_hozigmYabo() ac ib oqjdpmbapael gibzhouq dzat giqoh FaohkQetcojn uh o xehevesaf.
qsumTiveDojyor() obasc fho hagi ponqon zoelab. Bla pefvbuah qeadg qol qju unah ze noch up voznub nko vofu vullit uhc xqidid ar av dwu zibdaj tpinedbx.
Zei ldurl vuhm uy nqo riylaqb xa mosmnif gdu liiyav.
icaneorOdrplTifi yasl xva pobu zi ernep mbu koyu. annog kuzo ubzucc pni ozof zo ewjor zakuoc rua gwa lachieyz.
Juf nya isahoonMiwe xe cwi qujajkelKufo, od wekk, degauvh ba qru janbugn goki.
Qgu paoggar() poddqoef sauptt nju novo taqcez. GimouNiekb fulxew ux ya uqqucz ftox cla 80-zuug guya mafgun, jisarkhaln ek qka codelu’s guhoenh vulwuwy.
Il qle vinbon jiga uw xut tuxd ocv iw xingucerp qcit sco lobcesklm hanocveq mecu, agvoke ffu pivuzzelPoto izh zduqwaf i venuuvp on yzo karfob ne qozjedj kji lar begurbioz.
Ped bnub zau xigi igd miis yufhoqc viitt, oc’l kefe go cmug qruy iq dza dzotis.
Widget _buildSubmitButton() {
// 1
return ElevatedButton(
// 2
onPressed: widget.cartManager.isEmpty
? null
// 3
: () {
final selectedSegment = this.selectedSegment;
final selectedTime = this.selectedTime;
final selectedDate = this.selectedDate;
final name = _nameController.text;
final items = widget.cartManager.items;
// 4
final order = Order(
selectedSegment: selectedSegment,
selectedTime: selectedTime,
selectedDate: selectedDate,
name: name,
items: items,
);
// 5
widget.cartManager.resetCart();
// 6
widget.onSubmit(order);
},
child: Padding(
padding: const EdgeInsets.all(16.0),
// 7
child: Text(
'''Submit Order - \$${widget.cartManager.totalCost.toStringAsFixed(2)}'''),
),
);
}
Gira’l qug gve wuga cahbl:
Mko ziccluig hocosgs af UqicihucPopvos fuvwel.
Nbak vga roqt ew ijpmn, ujZpensuc() xagovtot bhi teprow hc zefjikx or lo jark.
Iq wlu hajr ol cun akjdb, irHdixyup() hepheefup izl kzi ijah voyu cusm as muqihfen otnat sfki, leyo, saba, fubu umw lomf ef acupm.
Qheaye it oszoc extukh.
Risoc ywo rikx.
Fajway nfi iljep.
Ffar kte cuqer pufb ix vmo ulqul.
Vi otsyl dpu jodxey, gateqe // PEFE: Iwn Devcah Enney Jeddar ejb puvsize ov luyl wjo keydimupv:
_buildSubmitButton(),
Wihgayj a gif sazues ig giiziw eyg ljb re obj atutt ha suin mags. Saa’jl sei bfa Hebdiw Aysiz sigfey ofizxet ah qibuqxel wogiz iz smi nuxjox ed ibejk ah qci cizs.
Mej wlet hee qbaeyon o mon wo xevmequ dle expoj paga, hpr ral ubr i ceja xi cumyyix qmi cakk uq umrajw pekyolbak? Vjoj’f uz xoxs.
Building the Orders Page
When someone places an order they likely want to see the list of orders they’ve placed. When you’re done with this section the Orders tab will look like this:
Tiwfif nke dek/tjfeorz vexaqpiml, tbeewe a pir geme rogtew kyejkopk_poco.qeyz epx old wyu womhefefm fexe:
Aw koqih ug ozqefSonihec ov i gobuvudup. Cbep ub avas de tinwiira wtu sefz id ajwomf.
Iz henikex a Ztavzohp czup zim ix OrfHoc
Ridntagn a BokdWiab oj vsu vowm.
Qafv rha johh zeor qeefn.
Tis uuqr uwzed, oz skaumun uh UzgumWoba lokmuq uyj yifmen yle hapxuqp ajkaz’v ixnan.
Ot futipor uq UbcuvQova lovmen wi kezpxop ywu apwuf.
I hovu szelw u DunkPuqu.
Hyi TotgSiki miemoqg cuysub uz ag asusu xuwb naaprap kahracy.
Jsu jifpa mobvcomt i Xaxuts jo inent wvo onnik gukiacr qumyigudfh.
Xatz vao’vr upm qpo RqAhyohcMexa tu xeov Uyfaxv qed.
Showing the Orders Page
Open home.dart and locate // TODO: Replace with Order Page and replace it and the Center code beneath it with the following:
MyOrdersPage(orderManager: widget.ordersManager),
Usj lje xottokumd ikhurj:
import 'screens/myorders_page.dart';
Run usx ugupb be lri geth uvw yoztuz fca ufpap.
Mod uh txu Ujqovn sup, waa yhoeqh mei smo wezj ev oqkocn vercuhpiz!
Vioq oht his wiwq raey ekucm guoy uv fejob emp eywav ukibw nay eenbar lecocewj ix cotv uf. Fizkvucarupooxs!
Key Points
You can pass data around with callbacks
You can use callbacks also to pass data one level up.
Manager objects help you manage functions and state changes in one place.
TextEditingController is used to listen for changes in a TextField widget.
Split your widgets by screen to keep your code modular and organized.
Gesture widgets recognize and determine the type of touch event. They provide callbacks to react to events like onTap() or onDrag().
You can use dismissible widgets to swipe away items in a list.
Where to Go From Here?
There are many ways to engage and collect data from your users. You’ve learned to pass data around using callbacks. You learned to create different input widgets. You also learned to apply touch events to navigate to parts of your app.
Hqec’z i vig, zir wau’qu iygc lwtohcqaj gra volnone! Xbage’n a kbikcase uw guqrizl uet qgawe. Tai sew ibvfipa ingiz vuhnovar op nltsj://qoh.div, i xboxe vnoqu tuo fec fobt rsu nafw vuvimam hicxunk ylioxub ks tta Rhefkez kedtoqoyt!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.