Flutter DraggableScrollableSheet 范围控制

Flutter DraggableScrollableSheet extent control

我正在尝试实现一个 DraggableScrollableSheet,它在我执行向上拖动操作时展开为 maxChildSize,而在我执行向下拖动操作时折叠为 minChildSize。我想知道如何控制 sheet.

的范围
DraggableScrollableSheet(
    initialChildSize: 0.75,
    minChildSize: 0.65,
    maxChildSize: 1.0,
    builder: (context, _scrollController) {
        return ListView(
            physics: ClampingScrollPhysics(),
            controller: _scrollController,
            children: [Widget A, Widget B, Widget C...],
        );
    },
)

我试着用这样的 GestureDetector 包裹 sheet

GestureDetector(
    onVerticalDragEnd:(details) {print("drag ended");},
    child:DraggableScrollableSheet(
        initialChildSize: 0.75,
        minChildSize: 0.65,
        maxChildSize: 1.0,
        builder: (context, _scrollController) {
            return ListView(
                physics: ClampingScrollPhysics(),
                controller: _scrollController,
                children: [Widget A, Widget B, Widget C...],
            );
        },
    ),
)

但是 onVerticalDragEnd 没有做任何事情,甚至没有打印出消息。

我找到了使用 DraggableScrollableActuator 的建议, 它可以通过更改 initialChildSize 并调用 DraggableScrollableActuator.reset() 来完成我想要的操作,但是我找不到任何方法来使其动画化或平滑地更改 sheet 大小。

有什么方法可以在 DraggableScrollableSheet 中执行 .animateTo() 之类的操作吗?

https://github.com/flutter/flutter/issues/102520

虽然上面的问题没有直接问你上面的问题,但是我相信maheshmnj提供的答案。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<Color> colors = [
    Colors.green.shade400,
    Colors.green.shade900,
  ];
  late DraggableScrollableController _controller;

  @override
  void initState() {
    _controller = DraggableScrollableController();
    super.initState();
  }

  double initialSize = 1.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: DraggableScrollableSheet(
        controller: _controller,
        initialChildSize: initialSize,
        minChildSize: 0,
        maxChildSize: 1,
        builder: (context, controller) {
          return Container(
            color: Colors.blueGrey.shade100,
            child: ListView.builder(
              controller: controller,
              itemCount: 30,
              itemBuilder: (context, index) {
                return Container(
                  margin: const EdgeInsets.fromLTRB(20, 10, 20, 0),
                  height: 30,
                  color: colors[index % colors.length],
                  child: Center(child: Text('$index')),
                );
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await _controller.animateTo(
            _controller.size - 0.2,
            duration: Duration(milliseconds: 100),
            curve: Curves.linear,
          );
          setState(() {
            initialSize = _controller.size;
          });
        },
        child: const Icon(Icons.expand_more),
      ),
    );
  }
}