Best seller list view & Custom scroll view
Presentation (Building the UI)
Summary
This lesson focuses on building the "Best Seller" list view and integrating it into the home screen layout. The instructor explains the UX flaw of having nested scrollable areas and introduces CustomScrollView with slivers to make the entire screen scroll as a unified view. He demonstrates wrapping standard widgets in a SliverToBoxAdapter and refactors the layout to use SliverFillRemaining to handle the remaining vertical space without heavily penalizing performance.
Key Ideas
ListView.builderprovides efficient, lazy-loaded list rendering for standard layouts.- Nested scroll views (e.g., a scrollable list inside a scrollable column) create confusing and clunky user experiences.
CustomScrollViewallows multiple scrollable and non-scrollable widgets to scroll together seamlessly on a single screen.SliverToBoxAdapteracts as a bridge, allowing standard box-based widgets (likeColumnorPadding) to be placed inside a sliver array.shrinkWrap: trueforces aListViewto compute its entire height at once, which destroys the performance benefits of lazy loading.NeverScrollableScrollPhysicsprevents a nestedListViewfrom intercepting scroll gestures, delegating the scroll action entirely to the parent view.SliverFillRemainingforces its child to fill all the remaining viewport space in aCustomScrollView.
Code Snippets
import 'package:bookly/features/home/presentation/views/widgets/best_seller_list_view_item.dart';
import 'package:flutter/material.dart';
class BestSellerListView extends StatelessWidget {
const BestSellerListView({super.key});
@override
Widget build(BuildContext context) {
return ListView.builder(
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemCount: 10,
itemBuilder: (context, index) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: BestSellerListViewItem(),
);
},
);
}
}import 'package:bookly/core/utils/styles.dart';
import 'package:bookly/features/home/presentation/views/widgets/best_seller_list_view.dart';
import 'package:bookly/features/home/presentation/views/widgets/custom_app_bar.dart';
import 'package:bookly/features/home/presentation/views/widgets/featured_list_view.dart';
import 'package:flutter/material.dart';
class HomeViewBody extends StatelessWidget {
const HomeViewBody({super.key});
@override
Widget build(BuildContext context) {
return const CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: CustomAppBar(),
),
FeaturedBooksListView(),
SizedBox(
height: 50,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Text(
'Best Seller',
style: Styles.textStyle18,
),
),
SizedBox(
height: 20,
),
],
),
),
SliverFillRemaining(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: BestSellerListView(),
),
),
],
);
}
}Architecture Insight
CustomScrollView and slivers compose multiple scrollables — useful when you have heterogeneous content (featured row + best-seller column) but easy to over-use.
CA-wise, scroll behavior is presentation-only; never let a raw scroll position bleed into a Cubit's business state. The exception is when the position is genuinely meaningful — infinite-scroll page index, for example, *is* business state.
Looking ahead — Pagination state in section 5 is the one case where scroll position becomes a Cubit's business.
My Notes
The instructor tackles the classic "nested list" scrolling issue in Flutter. His first instinct—using shrinkWrap: true on the ListView—is a common anti-pattern that he correctly identifies as a performance bottleneck because it forces the list to render all items synchronously.
However, his final solution (SliverFillRemaining wrapping a ListView with NeverScrollableScrollPhysics and *no* shrinkWrap) is flawed. By restricting the ListView to the remaining screen height and disabling its internal scroll, any items that fall below the viewport fold become permanently unreachable.
`[Editor's note]`: The correct, performant way to build a scrollable page containing a list is to use SliverList (or SliverList.builder via SliverChildBuilderDelegate) directly in the CustomScrollView's slivers array. This delegates both layout and scrolling to the sliver protocol natively, preserving lazy loading without viewport restrictions.