Skip to content

[Proposal] Add "isAttached" property to DraggableScrollableController #99994

@vandir

Description

@vandir

Please consider adding a method like isAttached to DraggableScrollableController (I've seen the source code, it seems as simple as doing _attachedController != null) in order to know when the DraggableScrollableSheet attaches to a controller. This is useful to solve the problem described in #99508.

Alternative solution to problem #99508 (click to expand)
import 'package:flutter/material.dart';

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

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

  // This widget is the root of your application.
  @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();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: DraggableScrollableSheet(
        controller: _controller,
        initialChildSize: _controller.isAttached ? _controller.size : 0.25,
        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: const Duration(seconds: 3),
            curve: Curves.linear,
          );
          setState(() {});
        },
        child: const Icon(Icons.expand_more),
      ),
    );
  }
}

Mainly, there are two advantages over this solution:

  1. avoid an extra member field and looks more natural;
  2. avoid to set the member field to _controller.size every time I call setState() (which could be high)

As a result, the code looks much cleaner. Alternatively (maybe even better) you could consider to ignore the property initialChildSize when a DraggableScrollableController is attached.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterf: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.r: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions