fix: scrolling in filter widget (#2792)

malik1004x committed Jan 7, 2026 at 20:18 UTC f2508d1eb449d85a19466c6b3fe9f52a8ccd5ebd
1 file changed +73 -100
lib/src/screens/dashboard/widgets/filter_widget.dart
+73 -100
@@ -3,7 +3,6 @@ import 'package:cake_wallet/src/widgets/alert_close_button.dart';
3 import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart';
4 import 'package:cake_wallet/src/widgets/section_divider.dart';
5 import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
6 -import 'package:cake_wallet/utils/responsive_layout_util.dart';
6 import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
7 import 'package:flutter/material.dart';
8 import 'package:cake_wallet/generated/i18n.dart';
@@ -20,14 +19,6 @@ class FilterWidget extends StatefulWidget {
19 }
20
21 class _FilterWidgetState extends State<FilterWidget> {
23 - final ScrollController _scrollController = ScrollController();
24 -
25 - @override
26 - void dispose() {
27 - _scrollController.dispose();
28 - super.dispose();
29 - }
30 -
22 @override
23 Widget build(BuildContext context) {
24 return AlertBackground(
@@ -55,108 +46,90 @@ class _FilterWidgetState extends State<FilterWidget> {
46 Widget _buildFilterContent(BuildContext context, double availableHeight) {
47 const sectionDivider = HorizontalSectionDivider();
48
58 - const double totalHeaderHeight = 73;
59 - const double filterTileMinHeight = 40;
60 - double availableHeightForItems = availableHeight - totalHeaderHeight;
61 -
49 return Center(
50 child: Column(
51 mainAxisSize: MainAxisSize.min,
52 children: [
53 Padding(
54 padding: const EdgeInsets.only(left: 24, right: 24, top: 24),
68 - child: ClipRRect(
69 - borderRadius: BorderRadius.circular(24),
70 - child: Container(
71 - color: Theme.of(context).colorScheme.surface,
72 - child: Column(
73 - crossAxisAlignment: CrossAxisAlignment.start,
74 - children: [
75 - Padding(
76 - padding: const EdgeInsets.all(24.0),
77 - child: Align(
78 - alignment: Alignment.center,
79 - child: Text(
80 - S.of(context).filter_by,
81 - style: Theme.of(context).textTheme.titleMedium?.copyWith(
82 - color: Theme.of(context).colorScheme.onSurface,
83 - fontWeight: FontWeight.bold,
55 + child: ConstrainedBox(
56 + constraints: BoxConstraints(
57 + maxHeight: MediaQuery.of(context).size.height * 0.7,
58 + ),
59 + child: ClipRRect(
60 + borderRadius: BorderRadius.circular(24),
61 + child: Container(
62 + color: Theme.of(context).colorScheme.surface,
63 + child: Column(
64 + mainAxisSize: MainAxisSize.min,
65 + crossAxisAlignment: CrossAxisAlignment.start,
66 + children: [
67 + Padding(
68 + padding: const EdgeInsets.all(24.0),
69 + child: Align(
70 + alignment: Alignment.center,
71 + child: Text(
72 + S.of(context).filter_by,
73 + style: Theme.of(context).textTheme.titleMedium?.copyWith(
74 + color: Theme.of(context).colorScheme.onSurface,
75 + fontWeight: FontWeight.bold,
76 + ),
77 ),
78 ),
79 ),
87 - ),
88 - sectionDivider,
89 - ListView.separated(
90 - padding: EdgeInsets.zero,
91 - shrinkWrap: true,
92 - physics: const NeverScrollableScrollPhysics(),
93 - itemCount: widget.filterItems.length,
94 - separatorBuilder: (context, _) => sectionDivider,
95 - itemBuilder: (_, index1) {
96 - final title = widget.filterItems.keys.elementAt(index1);
97 - final section = widget.filterItems.values.elementAt(index1);
98 -
99 - final double itemHeight =
100 - availableHeightForItems / widget.filterItems.length;
80 + sectionDivider,
81 + Flexible(
82 + fit: FlexFit.loose,
83 + child: ListView.separated(
84 + shrinkWrap: true,
85 + padding: EdgeInsets.zero,
86 + itemCount: widget.filterItems.length,
87 + separatorBuilder: (context, _) => sectionDivider,
88 + itemBuilder: (_, index1) {
89 + final title = widget.filterItems.keys.elementAt(index1);
90 + final section = widget.filterItems.values.elementAt(index1);
91
102 - final isSectionScrollable =
103 - (itemHeight < (section.length * filterTileMinHeight));
104 -
105 - final Widget sectionListView = ListView.builder(
106 - controller: isSectionScrollable ? _scrollController : null,
107 - padding: const EdgeInsets.symmetric(horizontal: 28.0, vertical: 8.0),
108 - shrinkWrap: isSectionScrollable ? false : true,
109 - physics: isSectionScrollable
110 - ? const BouncingScrollPhysics()
111 - : const NeverScrollableScrollPhysics(),
112 - itemCount: section.length,
113 - itemBuilder: (_, index2) {
114 - final item = section[index2];
115 - final content = Observer(
116 - builder: (_) => StandardCheckbox(
117 - value: item.value(),
118 - caption: item.caption,
119 - gradientBackground: true,
120 - borderColor: Theme.of(context).colorScheme.outlineVariant,
121 - iconColor: Theme.of(context).colorScheme.onSurface,
122 - onChanged: (value) => item.onChanged(),
123 - ),
124 - );
125 - return FilterTile(
126 - child: content,
92 + return Column(
93 + crossAxisAlignment: CrossAxisAlignment.start,
94 + children: [
95 + Padding(
96 + padding: const EdgeInsets.only(top: 20, left: 24, right: 24),
97 + child: Text(
98 + title,
99 + style: Theme.of(context).textTheme.titleMedium?.copyWith(
100 + color: Theme.of(context).colorScheme.onSurface,
101 + fontWeight: FontWeight.bold,
102 + decoration: TextDecoration.none,
103 + ),
104 + ),
105 + ),
106 + ListView.builder(
107 + padding: const EdgeInsets.symmetric(horizontal: 28.0, vertical: 8.0),
108 + shrinkWrap: true,
109 + physics: const NeverScrollableScrollPhysics(),
110 + itemCount: section.length,
111 + itemBuilder: (_, index2) {
112 + final item = section[index2];
113 + final content = Observer(
114 + builder: (_) => StandardCheckbox(
115 + value: item.value(),
116 + caption: item.caption,
117 + gradientBackground: true,
118 + borderColor: Theme.of(context).colorScheme.outlineVariant,
119 + iconColor: Theme.of(context).colorScheme.onSurface,
120 + onChanged: (value) => item.onChanged(),
121 + ),
122 + );
123 + return FilterTile(child: content);
124 + },
125 + ),
126 + ],
127 );
128 },
129 - );
130 -
131 - return Column(
132 - crossAxisAlignment: CrossAxisAlignment.start,
133 - children: [
134 - Padding(
135 - padding: const EdgeInsets.only(top: 20, left: 24, right: 24),
136 - child: Text(
137 - title,
138 - style: Theme.of(context).textTheme.titleMedium?.copyWith(
139 - color: Theme.of(context).colorScheme.onSurface,
140 - fontWeight: FontWeight.bold,
141 - decoration: TextDecoration.none,
142 - ),
143 - ),
144 - ),
145 - Container(
146 - height: isSectionScrollable ? itemHeight - totalHeaderHeight : null,
147 - child: isSectionScrollable
148 - ? Scrollbar(
149 - controller: _scrollController,
150 - thumbVisibility: true,
151 - child: sectionListView,
152 - )
153 - : sectionListView,
154 - ),
155 - ],
156 - );
157 - },
158 - ),
159 - ],
129 + ),
130 + ),
131 + ],
132 + ),
133 ),
134 ),
135 ),
@@ -165,4 +138,4 @@ class _FilterWidgetState extends State<FilterWidget> {
138 ),
139 );
140 }
168 -}
141 +}
\ No newline at end of file