使用拉动刷新文本而不是刷新图标并导航到新屏幕而不是任何未来或延迟

问题描述 投票:0回答:1

正文

我想要这样的行为,当用户下拉时,他会得到一个文本拉动来添加更多内容,当前屏幕上的小部件也随之向下拖动。
下拉显示文本并在发布时导航。

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(''),
                  ],
                ),
              ),
            ],
          ),
        ),
    );
  }
}

能够导航

flutter dart pull-to-refresh
1个回答
0
投票

使用custom_refresh_indicator为目的,

阅读这篇文章

需要注意的重要事项是AnimatedBuilderTransform

的功能

结果

在您想要的屏幕中调用指示器并指定 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...";
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.