-
需求:
开发中遇到需要iOS tableView 分组效果实现;随想封装一个通用的,所有类似界面都可复用的;组件带 headerBuilder 构建函数,itemBuilder 构建函数,可返回任意 Widget子组件;
screenshot:
- example:
SectionListView<String, Tuple2<String, String>>(
headerList: ["特殊功能", "系统组件demo", "自定义组件", "其它"],
itemList: [_specials, _list, _customeWidgets, _others],
headerBuilder: (e) {
return Text(e, style: TextStyle(fontWeight: FontWeight.w600),);
},
itemBuilder: (section, row, e) {
return ListTile(
title: Text(e.item2),
subtitle: Text(e.item2.toCapitalize()),
trailing: Icon(Icons.keyboard_arrow_right_rounded),
dense: true,
onTap: (){
// Get.toNamed(e.item1, arguments: e);
if (e.item1.toLowerCase().contains("loginPage".toLowerCase())){
Get.offNamed(e.item1, arguments: e.item1);
} else {
Get.toNamed(e.item1, arguments: e.item1);
}
},
);
},
)
- 源码
//
// SectionListView.dart
// fluttertemplet
//
// Created by shang on 10/15/21 3:00 PM.
// Copyright © 10/15/21 shang. All rights reserved.
//
import 'package:flutter/material.dart';
// import 'package:fluttertemplet/dartExpand/ddlog.dart';
///抽象封装
class SectionListView<H, E> extends StatefulWidget {
/// 表头背景色
final Color? headerColor;
/// 内边距
final EdgeInsetsGeometry? headerPadding;
final List<H> headerList;
final List<List<E>> itemList;
final Widget Function(H e) headerBuilder;
final Widget Function(int section, int row, E e) itemBuilder;
SectionListView({
Key? key,
this.headerColor,
this.headerPadding = const EdgeInsets.only(top: 10, bottom: 8, left: 15, right: 15),
this.headerList = const [],
required this.headerBuilder,
this.itemList = const [],
required this.itemBuilder,
}) : assert(itemList.length == headerList.length),
super(key: key);
@override
_SectionListViewState createState() => _SectionListViewState<H,E>();
}
class _SectionListViewState<H, E> extends State<SectionListView<H,E>> {
List<Widget> slivers = [];
@override
void initState() {
super.initState();
_updateSlivers();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
dynamic arguments = ModalRoute.of(context)!.settings.arguments;
return _buildBody();
}
Widget _buildBody() {
return CustomScrollView(
slivers: slivers,
);
}
Widget _buildHeader({required int section, required Widget child}) {
return
SliverToBoxAdapter(
child: Container(
color: Color(0xFFDDDDDD),
padding: widget.headerPadding,
child: child,
),
);
}
Widget _buildSliverList({required int section, required List<E> list}) {
final items = widget.itemList[section];
return SliverList(
delegate: SliverChildBuilderDelegate((_, int index)
=> widget.itemBuilder(section, index, items[index]),
childCount: items.length),
);
}
_updateSlivers() {
for(int i = 0; i < widget.headerList.length; i++) {
var headerItem = widget.headerList[i];
var items = widget.itemList[i];
slivers.add(_buildHeader(section: i, child: widget.headerBuilder(headerItem),
));
slivers.add(_buildSliverList(section: i, list: items.whereType<E>().toList()));
}
// ddlog([widget.sectionTitles.length, slivers.length]);
setState(() { });
}
}