我想要这样的行为,当用户下拉时,他会得到一个文本拉动来添加更多内容,当前屏幕上的小部件也随之向下拖动。
下拉显示文本并在发布时导航。
body: Column(
children: [
Expanded(
flex: 4,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Spent This Week',
style: kSmallDarkGreyTextStyle),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
textBaseline: TextBaseline.ideographic,
children: [
const Padding(
padding: EdgeInsets.all(3),
child: Text('₹', style: kBigDarkGreyTextStyle),
),
Text(
weekAverage.toStringAsFixed(2),
style: kBlackAmountTextStyle,
)
],
)
],
)),
Expanded(
flex: 5,
child: Column(
children: const [
Text(''),
],
),
),
],
),
我没有使用 RefreshIndicator,因为它不允许我更改刷新图标,我想用文本代替它。我搜索了不同的方法来实现它。
尝试使用它,将扩展小部件中的所有列项目更改为使用具有特定高度的小部件
import 'package:expense_manager/constants.dart';
import 'package:flutter/material.dart';
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart';
import 'package:responsive_sizer/responsive_sizer.dart';
import 'AddExpenditureScreen.dart';
class CurrentWeekScreen extends StatefulWidget {
static String id = 'current_week_screen';
@override
State<CurrentWeekScreen> createState() => _CurrentWeekScreenState();
}
class _CurrentWeekScreenState extends State<CurrentWeekScreen> {
late double weekAverage = 23454.99;
IndicatorController controller = IndicatorController();
onlyDecimal(double weekAverage) {}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: const Icon(
Icons.search,
color: Colors.black,
size: 28,
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(
Icons.add_circle_outlined,
color: Colors.black,
size: 28,
),
),
],
),
body: CustomRefreshIndicator(
builder: (BuildContext context, Widget child, IndicatorController controller) { return Text('Pull to refresh'); },
onRefresh: () async{
Navigator.pushNamed(context, AddExpenditureScreen.id);
},
child: ListView(
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
children: [
SizedBox(
height: 38.h,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Spent This Week', style: kSmallDarkGreyTextStyle),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
textBaseline: TextBaseline.ideographic,
children: [
const Padding(
padding: EdgeInsets.all(3),
child: Text('₹', style: kBigDarkGreyTextStyle),
),
Text(
weekAverage.toStringAsFixed(2),
style: kBlackAmountTextStyle,
)
],
)
],
),
),
SizedBox(
height: 60.h,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: const [
Text(''),
],
),
),
],
),
),
);
}
}
能够导航
使用custom_refresh_indicator为目的,
需要注意的重要事项是AnimatedBuilder和Transform
的功能在您想要的屏幕中调用指示器并指定 onAction 并提供一个ListView作为孩子
body:AddMoreIndicator(
onAction: () async {
await Future<void>.delayed(const Duration(milliseconds: 1000));
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddExpenditureScreen(
loggedInUser: loggedInUser,
)));
},
child: ListView(
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
children: [ .... ]
),
)
创建一个 swipe_action.dart 文件 =>
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart';
import 'package:flutter/material.dart';
import '../constants.dart';
const kPullToRefreshContentColor = Color(0xff877162);
class AddMoreIndicator extends StatelessWidget {
final Widget child;
final VoidCallback onAction;
const AddMoreIndicator({
Key? key,
required this.child,
required this.onAction,
}) : super(key: key);
@override
Widget build(BuildContext context) {
const height = 100.0;
return CustomRefreshIndicator(
onRefresh: () async => onAction(), //i need to animate to new screen
trigger: IndicatorTrigger.leadingEdge, // i need leading edge
child: child,
builder: (
BuildContext context,
Widget child,
IndicatorController controller,
) {
return AnimatedBuilder(
animation: controller,
builder: (context, _) {
final dy = controller.value.clamp(0.0, 1.25) *
-(height - (height * 0.25));
return Stack(
children: [
Transform.translate(
offset: Offset(0.0, -dy),
child: child,
),
Positioned(
top: -height,
left: 0,
right: 0,
height: height,
child: Container(
color: const Color(0x783453FF),
transform: Matrix4.translationValues(0.0, -dy, 0.0),
padding: const EdgeInsets.only(bottom: 30.0),
constraints: const BoxConstraints.expand(),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (controller.isLoading)
Container(
margin: const EdgeInsets.only(top: 8.0),
width: 16,
height: 16,
child: const CircularProgressIndicator(
color: kPullToRefreshContentColor,
strokeWidth: 2,
),
)
else
const Icon(
Icons.arrow_downward_rounded,
color: kPullToRefreshContentColor,
),
Text(
getText(controller),
style: const TextStyle(
color: kPullToRefreshContentColor,
),
)
],
),
),
),
],
);
});
},
);
}
String getText(IndicatorController controller) {
if (controller.isDragging || controller.isCanceling) {
return "Pull to Add expense";
} else {
return "Adding...";
}
}
}