From 59325fa0cfae4c42e56a53eead7b3b3078a8ef9b Mon Sep 17 00:00:00 2001 From: Badr Kouki Date: Mon, 14 Jul 2025 23:17:38 +0100 Subject: [PATCH] fix #149: resolve separator builder rendering issue --- example/lib/main.dart | 50 +++++++++++++++++++++++----- example/pubspec.lock | 18 +++++----- lib/searchable_listview.dart | 18 +++++----- lib/widgets/list_view_rendering.dart | 38 ++++++++++----------- 4 files changed, 79 insertions(+), 45 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 870fa6e..a887ac1 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:searchable_listview/resources/arrays.dart'; import 'package:searchable_listview/searchable_listview.dart'; void main() { @@ -48,6 +47,7 @@ class _ExampleAppState extends State { Actor(age: 66, name: 'Denzel', lastName: 'Washington'), Actor(age: 49, name: 'Ben', lastName: 'Affleck'), ]; + List filteredActors = []; final Map> mapOfActors = { 'test 1': [ @@ -64,6 +64,12 @@ class _ExampleAppState extends State { final TextEditingController searchTextController = TextEditingController(); + @override + void initState() { + super.initState(); + filteredActors = actors; + } + @override Widget build(BuildContext context) { return SizedBox( @@ -74,7 +80,7 @@ class _ExampleAppState extends State { Expanded( child: Padding( padding: const EdgeInsets.all(15), - child: renderSimpleSearchableList(), + child: renderAsynchSearchableListview(), ), ), Align( @@ -102,18 +108,44 @@ class _ExampleAppState extends State { return SearchableList( textAlignVertical: TextAlignVertical.center, searchFieldHeight: 40, - searchTextPosition: SearchTextPosition.bottom, lazyLoadingEnabled: false, + separatorBuilder: (context, index) { + return Container( + height: 40, + ); + }, sortPredicate: (a, b) => a.age.compareTo(b.age), itemBuilder: (item) { - return ActorItem(actor: item); + int index = filteredActors.indexOf(item); + if (index == 0) { + return Container( + color: Colors.red, + height: 10, + width: 300, + ); + } else { + return ActorItem(actor: filteredActors[index - 1]); + } }, + emptyWidget: Column( + children: [ + Container( + color: Colors.red, + height: 10, + width: 300, + ), + const Column( + children: [Icon(Icons.error), Text('No Data found')], + ) + ], + ), filter: (query) { - return actors + filteredActors = actors .where((element) => element.name.toLowerCase().contains(query.toLowerCase()) || element.lastName.toLowerCase().contains(query.toLowerCase())) .toList(); + return filteredActors; }, initialList: actors, ); @@ -121,7 +153,7 @@ class _ExampleAppState extends State { Widget renderSimpleSearchableList() { return SearchableList( - seperatorBuilder: (context, index) { + separatorBuilder: (context, index) { return const Divider(); }, textStyle: const TextStyle(fontSize: 25), @@ -196,8 +228,10 @@ class _ExampleAppState extends State { element.lastName.contains(query)) .toList(); }, - seperatorBuilder: (context, index) { - return const Divider(); + separatorBuilder: (context, index) { + return Container( + height: 30, + ); }, textStyle: const TextStyle(fontSize: 25), emptyWidget: const EmptyView(), diff --git a/example/pubspec.lock b/example/pubspec.lock index aa0004b..546815d 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.0" boolean_selector: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" flutter: dependency: "direct main" description: flutter @@ -79,10 +79,10 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: @@ -145,7 +145,7 @@ packages: path: ".." relative: true source: path - version: "2.17.2" + version: "2.19.0" sky_engine: dependency: transitive description: flutter @@ -211,10 +211,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "15.0.0" sdks: dart: ">=3.7.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/lib/searchable_listview.dart b/lib/searchable_listview.dart index 84a3c36..f33f315 100644 --- a/lib/searchable_listview.dart +++ b/lib/searchable_listview.dart @@ -56,7 +56,7 @@ class SearchableList extends StatefulWidget { this.reverse = false, this.sortPredicate, this.sortWidget, - this.seperatorBuilder, + this.separatorBuilder, this.scrollController, this.closeKeyboardWhenScrolling = false, this.displaySearchIcon = true, @@ -114,7 +114,7 @@ class SearchableList extends StatefulWidget { this.itemExtent, this.listViewPadding, this.reverse = false, - this.seperatorBuilder, + this.separatorBuilder, this.sortPredicate, this.sortWidget, this.scrollController, @@ -185,7 +185,7 @@ class SearchableList extends StatefulWidget { this.showSearchField = true, }) : super(key: key) { searchTextController ??= TextEditingController(); - seperatorBuilder = null; + separatorBuilder = null; isExpansionList = true; //! use itemBuiler instead of expansionTitleBuilder and expansionListBuilder itemBuilder = null; @@ -240,7 +240,7 @@ class SearchableList extends StatefulWidget { asyncListCallback = null; asyncListFilter = null; searchTextController ??= TextEditingController(); - seperatorBuilder = null; + separatorBuilder = null; sliverScrollEffect = true; onRefresh = null; shrinkWrap = false; @@ -361,7 +361,7 @@ class SearchableList extends StatefulWidget { /// Builder callback required when using [seperated] constructor /// return the Widget that will seperate all the elements inside the list - late Widget Function(BuildContext context, int index)? seperatorBuilder; + late Widget Function(BuildContext context, int index)? separatorBuilder; /// The scroll direction of the list /// by default [Axis.vertical] @@ -627,8 +627,8 @@ class _SearchableListState extends State> { isLazyLoadingEnabled: widget.lazyLoadingEnabled, list: list, itemBuilder: widget.itemBuilder, - isListViewSeparated: widget.seperatorBuilder != null, - seperatorBuilder: widget.seperatorBuilder, + isListViewSeparated: widget.separatorBuilder != null, + seperatorBuilder: widget.separatorBuilder, ), ) : ListViewRendering( @@ -642,8 +642,8 @@ class _SearchableListState extends State> { isLazyLoadingEnabled: widget.lazyLoadingEnabled, list: list, itemBuilder: widget.itemBuilder, - isListViewSeparated: widget.seperatorBuilder != null, - seperatorBuilder: widget.seperatorBuilder, + isListViewSeparated: widget.separatorBuilder != null, + seperatorBuilder: widget.separatorBuilder, ); } } diff --git a/lib/widgets/list_view_rendering.dart b/lib/widgets/list_view_rendering.dart index 463aea2..e029912 100644 --- a/lib/widgets/list_view_rendering.dart +++ b/lib/widgets/list_view_rendering.dart @@ -32,7 +32,19 @@ class ListViewRendering extends StatelessWidget { @override Widget build(BuildContext context) { - if (isLazyLoadingEnabled) { + if (isListViewSeparated) { + return ListView.separated( + controller: scrollController, + scrollDirection: scrollDirection, + itemCount: list.length, + physics: physics, + shrinkWrap: shrinkWrap, + padding: padding, + reverse: reverse, + itemBuilder: (context, index) => itemBuilder!(list[index]), + separatorBuilder: seperatorBuilder!, + ); + } else if (isLazyLoadingEnabled) { return ListView( physics: physics, shrinkWrap: shrinkWrap, @@ -45,30 +57,18 @@ class ListViewRendering extends StatelessWidget { return itemBuilder!(item); }).toList(), ); - } - if (isListViewSeparated) { - return ListView.separated( - controller: scrollController, - scrollDirection: scrollDirection, - itemCount: list.length, + } else { + return ListView.builder( physics: physics, shrinkWrap: shrinkWrap, + itemExtent: itemExtent, padding: padding, reverse: reverse, + controller: scrollController, + scrollDirection: scrollDirection, + itemCount: list.length, itemBuilder: (context, index) => itemBuilder!(list[index]), - separatorBuilder: seperatorBuilder!, ); } - return ListView.builder( - physics: physics, - shrinkWrap: shrinkWrap, - itemExtent: itemExtent, - padding: padding, - reverse: reverse, - controller: scrollController, - scrollDirection: scrollDirection, - itemCount: list.length, - itemBuilder: (context, index) => itemBuilder!(list[index]), - ); } }