初始化
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hgdj/assets_tool/app_colors.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
|
||||
// 回弹弹簧:临界阻尼(≈2√(stiffness·mass)=34.6) → 松手快速收回不过冲
|
||||
// 注:实测此调优手感优于 3.16.8 包默认(mass2.2/stiffness150/damping16,欠阻尼、回弹更夸张),
|
||||
// 故采用这套调优值,不复刻 3.16.8 原值
|
||||
// 提成常量供横向的 HorizontalLoadMore 复用,两处手感必须一致,改这里即全改
|
||||
const SpringDescription kRefreshSpring =
|
||||
SpringDescription(mass: 1.5, stiffness: 200, damping: 35);
|
||||
const double kRefreshDragSpeedRatio = 0.91;
|
||||
|
||||
Widget pullYsRefresh({
|
||||
required RefreshViewOnInit onInit,
|
||||
required Widget child,
|
||||
Key? key,
|
||||
final Function(RefreshController? ctr)? onRefresh,
|
||||
final Function(RefreshController? ctr)? onLoading,
|
||||
bool enablePullUp = true,
|
||||
bool enablePullDown = true,
|
||||
String noDataText = "—— 没有更多数据了 ——",
|
||||
Widget? customHeader,
|
||||
Widget? footerHeader,
|
||||
}) {
|
||||
return CustomRefreshView(
|
||||
onInit: onInit,
|
||||
onLoading: onLoading,
|
||||
onRefresh: onRefresh,
|
||||
customHeader: customHeader,
|
||||
footerHeader: footerHeader,
|
||||
enablePullDown: enablePullDown,
|
||||
enablePullUp: enablePullUp,
|
||||
noDataText: noDataText,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
typedef RefreshViewOnInit = Function(RefreshController controller);
|
||||
|
||||
class CustomRefreshView extends StatefulWidget {
|
||||
final bool enablePullDown;
|
||||
final bool enablePullUp;
|
||||
final Function(RefreshController? ctr)? onRefresh;
|
||||
final Function(RefreshController? ctr)? onLoading;
|
||||
final Widget? customHeader;
|
||||
final Widget? footerHeader;
|
||||
final Widget child;
|
||||
final String noDataText;
|
||||
final RefreshViewOnInit onInit;
|
||||
|
||||
const CustomRefreshView({
|
||||
super.key,
|
||||
required this.child,
|
||||
required this.onInit,
|
||||
this.enablePullDown = true,
|
||||
this.enablePullUp = true,
|
||||
this.onRefresh,
|
||||
this.onLoading,
|
||||
this.customHeader,
|
||||
this.footerHeader,
|
||||
this.noDataText = "—— 没有更多数据了 ——",
|
||||
});
|
||||
|
||||
@override
|
||||
State<CustomRefreshView> createState() => _CustomIRefreshViewState();
|
||||
}
|
||||
|
||||
class _CustomIRefreshViewState extends State<CustomRefreshView> {
|
||||
final refreshCtr = RefreshController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
widget.onInit(refreshCtr);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
//组件创建的 controller 由组件释放(谁创建谁释放)
|
||||
refreshCtr.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshConfiguration(
|
||||
springDescription: kRefreshSpring,
|
||||
dragSpeedRatio: kRefreshDragSpeedRatio,
|
||||
maxOverScrollExtent: 60,
|
||||
maxUnderScrollExtent: 0,
|
||||
enableBallisticRefresh: false, // 下拉不靠惯性触发刷新
|
||||
enableBallisticLoad: true, // 上拉滑到底自动加载
|
||||
//去掉 StretchingOverscrollIndicator,避免与下拉刷新冲突
|
||||
child: ScrollConfiguration(
|
||||
behavior: NoStretchScrollBehavior(),
|
||||
child: SmartRefresher(
|
||||
enablePullDown: widget.enablePullDown,
|
||||
enablePullUp: widget.enablePullUp,
|
||||
controller: refreshCtr,
|
||||
onRefresh: () => widget.onRefresh?.call(refreshCtr),
|
||||
onLoading: () => widget.onLoading?.call(refreshCtr),
|
||||
header: widget.customHeader ??
|
||||
WaterDropHeader(
|
||||
waterDropColor: AppColors.actionRed,
|
||||
// iOS 刷新菊花用主题色;Android 保持默认 loading
|
||||
refresh: Platform.isIOS
|
||||
? const CupertinoActivityIndicator(
|
||||
color: AppColors.actionRed)
|
||||
: null,
|
||||
complete: const Text(
|
||||
"刷新完成!",
|
||||
style: TextStyle(
|
||||
color: AppColors.tipTextColor99, fontSize: 12),
|
||||
),
|
||||
failed: const Text(
|
||||
"刷新失敗!",
|
||||
style: TextStyle(
|
||||
color: AppColors.tipTextColor99, fontSize: 12),
|
||||
),
|
||||
),
|
||||
footer: widget.footerHeader ??
|
||||
ClassicFooter(
|
||||
loadingText: "加载中...",
|
||||
canLoadingText: "松开加载更多...",
|
||||
noDataText: widget.noDataText,
|
||||
idleText: "上拉加载更多",
|
||||
// Android 默认转圈是蓝色,改成主题色;iOS 保持菊花
|
||||
loadingIcon: SizedBox(
|
||||
width: 25,
|
||||
height: 25,
|
||||
child: Platform.isIOS
|
||||
? const CupertinoActivityIndicator()
|
||||
: const CircularProgressIndicator(
|
||||
strokeWidth: 2.0,
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation(AppColors.actionRed),
|
||||
),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: AppColors.tipTextColor99,
|
||||
fontSize: 12,
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
child: widget.child),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//还原 Flutter 3.16 时代的滚动行为
|
||||
class NoStretchScrollBehavior extends MaterialScrollBehavior {
|
||||
//去掉 StretchingOverscrollIndicator,避免与下拉刷新冲突
|
||||
@override
|
||||
Widget buildOverscrollIndicator(
|
||||
BuildContext context,
|
||||
Widget child,
|
||||
ScrollableDetails details,
|
||||
) {
|
||||
return child;
|
||||
}
|
||||
|
||||
//还原旧版多指拖拽策略(3.19+ 改为 latestPointer,拖拽手感有细微差异)
|
||||
@override
|
||||
MultitouchDragStrategy getMultitouchDragStrategy(BuildContext context) {
|
||||
return MultitouchDragStrategy.averageBoundaryPointers;
|
||||
}
|
||||
|
||||
//使用 BouncingScrollPhysics 还原弹性下拉手感
|
||||
@override
|
||||
ScrollPhysics getScrollPhysics(BuildContext context) {
|
||||
return const BouncingScrollPhysics();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user