Flutter DraggableScrollableSheet - 如何以编程方式展开/折叠

And*_*dre 15 flutter flutter-layout

我想知道是否有人知道/找到了一种以编程方式使 Flutters 的 DraggableScrollableSheet 展开/折叠的方法。我正在使用他们的 Dev 频道中的 Flutters 最新版本,这允许我将它包装在一个

NotificationListener<DraggableScrollableNotification>
Run Code Online (Sandbox Code Playgroud)

然后我可以听到床单展开/折叠的程度。但是,我不清楚如何折叠展开的工作表,反之亦然。

似乎在小部件 src 文件中有一个

DraggableScrollableActuator
Run Code Online (Sandbox Code Playgroud)

这暴露了一个静态的 .reset 但我不知道/或想出一种方法来实现它。

gtr*_*iuk 11

以 Pierre 的回答为基础,我最终实施了一种解决方法,该方法允许我使用DraggableScrollableActuator折叠和扩展DraggableScrollableSheet.

您可以使用该setState方法更改 的值,initialChildSize然后使用该DraggableScrollableActuator.reset方法展开或折叠工作表。

void toggleDraggableScrollableSheet() {
  if (draggableSheetContext != null) {
    setState(() {
      initialExtent = isExpanded ? minExtent : maxExtent;
    });
    DraggableScrollableActuator.reset(draggableSheetContext);
  }
}
Run Code Online (Sandbox Code Playgroud)

完成这项工作的重要一点是为Key小部件折叠和展开时提供不同的信息。这将导致 2 个实例_DraggableScrollableSheetState- 一个可以重置为折叠状态,另一个可以重置为展开状态。

DraggableScrollableActuator(
  child: DraggableScrollableSheet(
    key: Key(initialExtent.toString()),
    minChildSize: minExtent,
    maxChildSize: maxExtent,
    initialChildSize: initialExtent,
    builder: draggableScrollableSheetBuilder,
  ),
)
Run Code Online (Sandbox Code Playgroud)

编辑:

工作示例:

import 'package:flutter/material.dart';

void main() async {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  static const List<Color> colors = [
    Colors.red,
    Colors.green,
    Colors.blue,
  ];

  static const double minExtent = 0.2;
  static const double maxExtent = 0.6;

  bool isExpanded = false;
  double initialExtent = minExtent;
  BuildContext draggableSheetContext;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: _buildBody(),
      ),
    );
  }

  Widget _buildBody() {
    return InkWell(
      onTap: _toggleDraggableScrollableSheet,
      child: DraggableScrollableActuator(
        child: DraggableScrollableSheet(
          key: Key(initialExtent.toString()),
          minChildSize: minExtent,
          maxChildSize: maxExtent,
          initialChildSize: initialExtent,
          builder: _draggableScrollableSheetBuilder,
        ),
      ),
    );
  }

  void _toggleDraggableScrollableSheet() {
    if (draggableSheetContext != null) {
      setState(() {
        initialExtent = isExpanded ? minExtent : maxExtent;
        isExpanded = !isExpanded;
      });
      DraggableScrollableActuator.reset(draggableSheetContext);
    }
  }

  Widget _draggableScrollableSheetBuilder(
    BuildContext context,
    ScrollController scrollController,
  ) {
    draggableSheetContext = context;
    return SingleChildScrollView(
      controller: scrollController,
      child: Column(
        children: colors
            .map((color) => Container(
                  height: 200,
                  width: double.infinity,
                  color: color,
                ))
            .toList(),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 从来没听说过。github 存储库中有一个未解决的问题,要求向“DraggableScrollableActuator”添加“animateTo”方法来解决该问题:https://github.com/flutter/flutter/issues/45009 (2认同)

mig*_*uno 11

有一个新的解决方案可用 - 可以在稳定通道中使用。

通过使用 new,DraggableScrollableController您现在可以通过编程方式显示或隐藏带DraggableScrollableSheet或不带动画的动画。

class TestWidget extends StatelessWidget {
  final controller = DraggableScrollableController();
  final minChildSize = 0.2;

  @override
  Widget build(BuildContext context) {
    return DraggableScrollableSheet(
      controller: controller,
      minChildSize: minChildSize,
      builder: _buildBody(),
    );
  }

  void animatedHide() {
    controller.animateTo(
      minChildSize,
      duration: const Duration(milliseconds: 100),
      curve: Curves.easeOutBack,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

此处提供的文档:https ://api.flutter.dev/flutter/widgets/DraggableScrollableController-class.html


Pie*_*her 5

您可以使用重置DraggableScrollableSheet的位置。因此,您需要拥有由 DraggableScrollableSheet 构建器参数提供给您的 。initialChildSizeDraggableScrollableActuatorBuildContext

例如,您可以在 中创建一个 ButtonDraggableScrollableSheet并调用DraggableScrollableActuator.reset(context);

DraggableScrollableSheet(
  builder: (BuildContext context, ScrollController scrollController) {

    return MaterialButton(
      onPressed: () {
        DraggableScrollableActuator.reset(context);
      },
    );

  },
)
Run Code Online (Sandbox Code Playgroud)

如果要从DraggableScrollableSheet其构建函数外部重置,则需要创建 BuildContext 的属性,该属性可用于保存上下文DraggableScrollableSheet

  • FWIW,我提出了一个功能请求来扩展 DraggableScrollableSheet/Actuator API:https://github.com/flutter/flutter/issues/45009。 (4认同)