提交 c8decc92 authored 作者: 张国庆's avatar 张国庆

修改List 列表
上级 c72d6092
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_clx_base/flutter_clx_base.dart'; import 'package:flutter_clx_base/flutter_clx_base.dart';
import 'package:flutter_clx_base/widget/base_list_widget.dart'; import 'package:flutter_clx_base/widget/base_list_widget.dart';
import 'package:flutter_clx_base_example/sample/skeleton_item.dart';
// import 'package:rive/rive.dart'; // import 'package:rive/rive.dart';
class BaseListWidgetTest extends StatefulWidget { class BaseListWidgetTest extends StatefulWidget {
...@@ -48,20 +49,8 @@ class _BaseListWidgetTestState extends State<BaseListWidgetTest> { ...@@ -48,20 +49,8 @@ class _BaseListWidgetTestState extends State<BaseListWidgetTest> {
} }
}, },
pageSize: 10, pageSize: 10,
itemBuilder: (BuildContext context, int index, item) { itemBuilder: (context, index, item) {
return Container( return const SkeletonItem();
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey.withOpacity(0.5),
width: 0.5,
),
),
),
alignment: Alignment.center,
height: 100,
child: Text(item.toString()),
);
}, },
header: TaurusHeader( header: TaurusHeader(
skyColor: themeData.colorScheme.primary, skyColor: themeData.colorScheme.primary,
...@@ -77,6 +66,10 @@ class _BaseListWidgetTestState extends State<BaseListWidgetTest> { ...@@ -77,6 +66,10 @@ class _BaseListWidgetTestState extends State<BaseListWidgetTest> {
messageText: 'Last updated at %T'.tr, messageText: 'Last updated at %T'.tr,
), ),
startLoadWidget: Container( startLoadWidget: Container(
decoration: BoxDecoration(
color: themeData.colorScheme.primary,
borderRadius: BorderRadius.circular(10),
),
alignment: Alignment.center, alignment: Alignment.center,
width: double.infinity, width: double.infinity,
height: 300, height: 300,
......
import 'package:flutter/material.dart';
/// Skeleton list item.
class SkeletonItem extends StatelessWidget {
/// Scrollable direction.
final Axis direction;
const SkeletonItem({
Key? key,
this.direction = Axis.vertical,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final themeData = Theme.of(context);
final backgroundColor = themeData.colorScheme.surfaceVariant;
final foregroundColor = themeData.colorScheme.surface;
if (direction == Axis.vertical) {
return Card(
elevation: 0,
color: backgroundColor,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(right: 16),
height: 80,
width: 80,
color: foregroundColor,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(top: 8, right: 24),
height: 12,
width: double.infinity,
constraints: const BoxConstraints(
maxWidth: 200,
),
color: foregroundColor,
),
Container(
margin: const EdgeInsets.only(top: 16),
height: 12,
width: 80,
color: foregroundColor,
),
Container(
margin: const EdgeInsets.only(top: 8),
height: 12,
width: 80,
color: foregroundColor,
),
],
),
),
],
),
),
);
}
return Card(
elevation: 0,
color: backgroundColor,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(bottom: 16),
height: 80,
width: 80,
color: foregroundColor,
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(left: 8, bottom: 24),
width: 12,
height: double.infinity,
constraints: const BoxConstraints(
maxHeight: 200,
),
color: foregroundColor,
),
Container(
margin: const EdgeInsets.only(left: 16),
width: 12,
height: 80,
color: foregroundColor,
),
Container(
margin: const EdgeInsets.only(left: 8),
width: 12,
height: 80,
color: foregroundColor,
),
],
),
),
],
),
),
);
}
}
...@@ -10,6 +10,8 @@ class BaseListWidget extends StatefulWidget { ...@@ -10,6 +10,8 @@ class BaseListWidget extends StatefulWidget {
final Header? header; final Header? header;
final Footer? footer; final Footer? footer;
final Widget? startLoadWidget; final Widget? startLoadWidget;
final Widget? emptyWidget;
final BaseListController? controller;
const BaseListWidget({ const BaseListWidget({
Key? key, Key? key,
...@@ -19,6 +21,8 @@ class BaseListWidget extends StatefulWidget { ...@@ -19,6 +21,8 @@ class BaseListWidget extends StatefulWidget {
this.header, this.header,
this.footer, this.footer,
this.startLoadWidget, this.startLoadWidget,
this.controller,
this.emptyWidget,
}) : super(key: key); }) : super(key: key);
@override @override
...@@ -26,23 +30,20 @@ class BaseListWidget extends StatefulWidget { ...@@ -26,23 +30,20 @@ class BaseListWidget extends StatefulWidget {
} }
class _BaseListWidgetState extends State<BaseListWidget> { class _BaseListWidgetState extends State<BaseListWidget> {
late EasyRefreshController _controller; late BaseListController _controller;
final List<dynamic> _dataList = []; final List<dynamic> _dataList = [];
int _page = 1; int _page = 1;
int _count = 0; int _count = 0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_controller = EasyRefreshController( _controller = widget.controller ?? BaseListController();
controlFinishRefresh: true,
controlFinishLoad: true,
);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return EasyRefresh( return EasyRefresh(
controller: _controller, controller: _controller.c,
refreshOnStart: true, refreshOnStart: true,
header: widget.header, header: widget.header,
footer: widget.footer, footer: widget.footer,
...@@ -70,18 +71,13 @@ class _BaseListWidgetState extends State<BaseListWidget> { ...@@ -70,18 +71,13 @@ class _BaseListWidgetState extends State<BaseListWidget> {
), ),
onRefresh: _onRefresh, onRefresh: _onRefresh,
onLoad: _onLoad, onLoad: _onLoad,
child: CustomScrollView( child: buildScrollView(),
slivers: [ );
SliverList( }
delegate: SliverChildBuilderDelegate(
(context, index) { Widget buildScrollView() {
return widget.itemBuilder(context, index, _dataList[index]); return CustomScrollView(
}, slivers: buildSlivers(),
childCount: _count,
),
),
],
),
); );
} }
...@@ -115,7 +111,7 @@ class _BaseListWidgetState extends State<BaseListWidget> { ...@@ -115,7 +111,7 @@ class _BaseListWidgetState extends State<BaseListWidget> {
_dataList.addAll(result!); _dataList.addAll(result!);
_count = _dataList.length; _count = _dataList.length;
}); });
_controller.finishLoad(result.length <= widget.pageSize _controller.c.finishLoad(result.length <= widget.pageSize
? IndicatorResult.noMore ? IndicatorResult.noMore
: IndicatorResult.success); : IndicatorResult.success);
} }
...@@ -126,6 +122,92 @@ class _BaseListWidgetState extends State<BaseListWidget> { ...@@ -126,6 +122,92 @@ class _BaseListWidgetState extends State<BaseListWidget> {
return; return;
} }
} }
/// Build header.
Header buildHeader() => EasyRefresh.defaultHeaderBuilder();
/// Build footer.
Footer buildFooter() => EasyRefresh.defaultFooterBuilder();
/// Check if there is no data.
bool get isEmpty => _count == 0;
dynamic getItem(int index) {
return _dataList[index];
}
List<Widget> buildSlivers() {
final header = buildHeader();
final footer = buildFooter();
Widget? emptyWidget;
if (isEmpty) {
emptyWidget = widget.emptyWidget;
}
return [
if (header.position == IndicatorPosition.locator)
const HeaderLocator.sliver(),
if (emptyWidget != null)
SliverFillViewport(
delegate: SliverChildBuilderDelegate(
(context, index) {
return emptyWidget;
},
childCount: 1,
),
),
buildSliver(),
if (footer.position == IndicatorPosition.locator)
const FooterLocator.sliver(),
];
}
/// Build sliver.
Widget buildSliver() {
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return buildItem(context, index, getItem(index));
},
childCount: _count,
),
);
}
/// Build item widget.
Widget buildItem(BuildContext context, int index, dynamic item) {
return widget.itemBuilder(context, index, item);
}
}
// 列表控制器
class BaseListController {
late EasyRefreshController _controller;
BaseListController() {
_controller = EasyRefreshController(
controlFinishRefresh: true,
controlFinishLoad: true,
);
}
void finishRefresh() {
_controller.finishRefresh();
}
void finishLoad() {
_controller.finishLoad();
}
void resetFooter() {
_controller.resetFooter();
}
// 重新加载数据
void reload() {
_controller.callRefresh();
}
get c => _controller;
} }
typedef RefreshCallback = Future<void> Function(); typedef RefreshCallback = Future<void> Function();
...@@ -134,4 +216,5 @@ typedef SuccessCallback = Function(List list); ...@@ -134,4 +216,5 @@ typedef SuccessCallback = Function(List list);
typedef ErrorCallback = Function(int code, String msg); typedef ErrorCallback = Function(int code, String msg);
typedef RequestDataCallback = Function( typedef RequestDataCallback = Function(
int page, int pageSize, SuccessCallback success, ErrorCallback error); int page, int pageSize, SuccessCallback success, ErrorCallback error);
typedef ItemBuilder = Function(BuildContext context, int index, dynamic item); typedef ItemBuilder = Function(
BuildContext context, int index, dynamic item);
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论