Flutter mimics iOS TableView group implementation
The background,
Flutter’s ListView or CustomScrollView supports a single column table and cannot be partited into groups, so group_tableView will help you do this.
Two, the implementation principle
The main function
function | Progress and Implementation |
---|---|
grouping | Plain, group |
Custom section Headers | support |
Custom section Footer | support |
Ability to add refreshes | support |
Emulate the iOS Group style
enum ViewStyle {
plain, //regular table view
group //sections are grouped together
}
Copy the code
Implementation principle of GroupListView
/// /// GroupListView implementation // class GroupListView extends StatefulWidget {final ViewStyle style; // ListView style, default is plain style final int numberOfSections; // Number of sections Default 1 Final SectionBuilder numberOfRowsInSection; // How many row Final IndexPathWidgetBuilder itemBuilder are in each section; // Final IndexedWidgetBuilder sectionHeaderBuilder; // Section Header Builder method Final IndexedWidgetBuilder sectionFooterBuilder; // Section Footer Builder method final ScrollController controller; // controller final Color backgroundColor; GroupListView({this.itemBuilder, this.style = viewstyle. plain, this.numberOfSections = 1, this.numberOfRowsInSection, this.sectionHeaderBuilder, this.sectionFooterBuilder, this.controller, this.backgroundColor}) : assert(itemBuilder ! = null, itemBuilder cannot be null); @override _GroupListViewState createState() => _GroupListViewState(); }Copy the code
This is currently implemented through listView.builer
@override
Widget build(BuildContext context) {
_initData();
return ListView.builder(
itemBuilder: _itemBuilder,
itemCount: _calculateItemCount(),
);
}
Copy the code
TotalCount = sectionHeader+sectionFooter+rows
int _calculateItemCount() { return totalCount; //row+section = total rows}Copy the code
Initialize the ListView according to the datasource
Void _initData() {totalCount = 0; sectionList.clear(); for (int section = 0; section < widget.numberOfSections; Section++) {/ / traversal section int rowCount = widget. The numberOfRowsInSection (section); // Get the number of row Widget headers per section; / / get the header if (widget sectionHeaderBuilder! = null) { header = widget.sectionHeaderBuilder(context, section); } Widget footer; / / get the footer if (widget sectionFooterBuilder! = null) { footer = widget.sectionFooterBuilder(context, section); } bool isHaveHeader = header ! = null ? true : false; Header bool isHaveFooter = footer! = null ? true : false; SectionModel = SectionModel(section, rowCount, isHaveHeader, isHaveFooter, header); if (section == 0) { currentSectionModel = sectionModel; } sectionList.add(sectionModel); totalCount = totalCount + rowCount + (header ! = null ? 1 : 0) + (footer ! = null ? 1:0); //ListView itemCount Total number of rows GlobalKey GlobalKey = GlobalKey(debugLabel: section.toString()); keyList.add(globalKey); } listView = ListView.builder( controller: _controller, physics: BouncingScrollPhysics(), itemBuilder: _itemBuilder, itemCount: _calculateItemCount(), ); }Copy the code
Listview. builder renders each row
Widget _itemBuilder(BuildContext context, int index) { Widget item; Object model = _getItemRowModel(index); if (model is SectionHeaderModel) { SectionHeaderModel sectionHeaderModel = model; item = widget.sectionHeaderBuilder(context, sectionHeaderModel.section); }else if(model is SectionFooterModel){ SectionFooterModel sectionFooterModel = model; item = widget.sectionFooterBuilder(context, sectionFooterModel.section); } else { RowModel rowModel = model; item = widget.itemBuilder(context, rowModel.indexPath); } return item; } Object _getItemRowModel(int index) { int passCount = 0; Row (int section = 0; row (int section = 0; section < sectionList.length; section++) { SectionModel sectionModel = this.sectionList[section]; bool isHaveHeader = sectionModel.isHaveHeader; bool isHaveFooter = sectionModel.isHaveFooter; int tempCount = 0; If (isHaveHeader == true) {// Have header tempCount = tempCount + 1; } if (index == passCount && isHaveHeader == true) {// This is header return SectionHeaderModel(section); }else if(index == tempCount + sectionModel.rowCount + passCount && isHaveFooter == true){// This is footer return SectionFooterModel(section); } else if (index >= passCount && index < tempCount + sectionModel.rowCount+passCount) {row IndexPath IndexPath = IndexPath(section, index - passCount - tempCount); return RowModel(indexPath); } passCount = passCount + sectionModel.rowCount + tempCount +(isHaveFooter? 1-0); } return null; }Copy the code
rendering
Source making
Group_tableview has been uploaded to Pub
If there is any help, please give a star, thanks 😁😁😁