简体   繁体   中英

How to allow Flutter drawer to close when it has Dismissible inside it?

I have an ending Drawer with a ListView of Dismissibles inside of it.

In each dismissible I have set 'direction: DismissDirection.endToStart'.

This correctly stops dissmising in the direction of the drawer close, but it doesn't close the drawer.

How do I allow the drawer to continue to close while still being able to dismiss to the other way?

I managed to solve your problem by using IgnorePointer and Listener as parents for your Dismissible .

When the user opens the drawer,he'll find that all Dismissibles are disabled by default, but a single swipe in the opposite direction of drawer closing will activate them. Which is marked here by the color change from grey to black.

To close the Drawer again you have to deactivate Dismissibles , which is done by a single small swipe, then you can easily close with an End to Start swipe.

I know you wanted to achieve a similar behavior without lifting the finger off the screen, but I couldn't manage to do this because changing state requires the pointer event to complete.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  final appTitle = 'Dismissibles demonstration';

  MyApp({Key key,}) : super(key: key);

  @override
 _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: widget.appTitle,
      home: MyHomePage(title: widget.appTitle),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState() ;
}

 class _MyHomePageState extends State<MyHomePage> {

   final items = List<String>.generate(100, (i) => "Item ${i + 1}");

   var ignoreSwitch = true ;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(child: Text('Example')),
      drawer: Drawer(
        child: Listener(
          onPointerMove: (PointerMoveEvent event) {
            print(event.delta.dx);
            if(event.delta.dx > 0.0){
              print('all items enabled');
              setState(() {
                      ignoreSwitch = false ;
                    });
            }
          },
          child: ListView.builder(
            itemCount: items.length,
            itemBuilder: (context, index) {
              final item = items[index];
              if(index == 0){
                return DrawerHeader(child: Text('Drawer Header',style: TextStyle(fontSize: 36.0),),decoration: BoxDecoration(color: Colors.cyan,),);
              }
              return Listener(
                onPointerMove: (PointerMoveEvent event) {
                  if(event.delta.dx > 0.0){
                    setState(() {
                      print('Inner listener working ! item $index enabled');
                      ignoreSwitch = false ;
                    });
                  }else{
                    setState(() {
                      print('Inner listener working ! item $index disabled');
                      ignoreSwitch = true ;
                    });
                  }
                },
                child: IgnorePointer(
                  ignoring: ignoreSwitch,
                  child: Dismissible(
                    key: Key(item),
                    direction: DismissDirection.startToEnd,
                    background: Container(
                      color: Colors.green,
                    ),
                    onDismissed: (direction) {
                      // Remove the item from our data source.
                      setState(() {
                        items.removeAt(index);
                      });
                    },
                    child: ListTileTheme(
                      textColor: ignoreSwitch ? Colors.grey : Colors.black,
                      style: ListTileStyle.drawer,
                      child: ListTile(
                        title: Text('item $index', style: TextStyle(fontSize: 18.0)),
                        onTap: () {
                          //Navigator.pop(context);
                        },
                      ),
                    )
                  ),
                ),
              );
            },
          ),
        )
      ),
    );
  }
}

在此处输入图片说明

try this:

Navigator.of(context).pop();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM