A handful of common Flutter UI needs — a TikTok-style vertical swipe feed, checkboxes, background images, and cleaning up the default debug banner — come up often enough in real apps to cover together.
A TikTok-style vertical scroll feed with PageView
PageView.builder(
scrollDirection: Axis.vertical,
itemCount: videos.length,
itemBuilder: (context, index) {
return VideoPlayerWidget(video: videos[index]);
},
)
PageView with scrollDirection: Axis.vertical is the core of this pattern — each swipe snaps fully to the next item, rather than allowing a partial scroll, which is exactly the full-screen, one-item-at-a-time feel a TikTok-style feed needs.
A standard scrollable list, for comparison
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index].name));
},
)
ListView scrolls freely and continuously, showing multiple items at once — the key difference from PageView is that ListView suits a normal scrolling list, while PageView suits full-screen, one-at-a-time paged content.
A generic scrollable container with SingleChildScrollView
SingleChildScrollView(
child: Column(
children: [
// any number of widgets that might overflow the screen height
],
),
)
SingleChildScrollView is the right choice when you have one long child (often a Column) that might not fit the screen, rather than a genuinely repeating list of items — using ListView for this instead works but is a slight misuse of a widget built for item-based, potentially very long lists.
A checkbox
bool _agreed = false;
CheckboxListTile(
title: Text('I agree to the terms'),
value: _agreed,
onChanged: (value) {
setState(() {
_agreed = value ?? false;
});
},
)
CheckboxListTile combines the checkbox with a tappable label in one widget — using a bare Checkbox alongside a separate Text widget works too, but means the text itself isn't tappable to toggle the checkbox, which is usually the better UX.
A background image
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/background.jpg'),
fit: BoxFit.cover,
),
),
child: Center(child: Text('Content over the background')),
)
BoxFit.cover scales the image to fill the container completely, cropping any excess — the standard choice for a full-screen background image where covering the whole area matters more than preserving the image's exact original aspect ratio.
Removing the debug banner
MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
)
The red "DEBUG" banner in the top-right corner only appears in debug builds and never in a release build — setting this flag simply removes it during development for cleaner screenshots or client demos, since it has no effect on the actual release build regardless of this setting.