如何在保持对话框打开的同时关闭抽屉?

时间:2020-09-14 11:18:15

标签: flutter

最小代码:

void main() => runApp(MaterialApp(home: MainPage()));

class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      drawer: MyDrawer(),
    );
  }
}

class MyDrawer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: RaisedButton(
        onPressed: () {
          // Close the Drawer, not the Dialog. 
          Timer(Duration(seconds: 2), () => Navigator.of(context, rootNavigator: true).pop());

          // Show the Dialog and keep it in opened state. 
          showDialog(
            context: context,
            builder: (_) => AlertDialog(title: Text('FooDialog')),
          );
        },
        child: Text('Show Dialog'),
      ),
    );
  }
}

按下按钮时,我将显示对话框,两秒钟后,我想关闭Drawer,同时保持Dialog在屏幕上打开。为此,我使用了Timer的{​​{1}}和rootNavigator属性。但是,我的对话框被关闭了。

除了使用Navigator的东西以外,是否还有其他解决方案来关闭抽屉?

2 个答案:

答案 0 :(得分:1)

[Theory]
[MemberData(nameof(TestData))]
public void Test(int test1, int test2, int expected)
{
    var result = test1 + test2;
    Assert.Equal(expected, result);
}

public static IEnumerable<object[]> TestData()
{
    for (var i = 0; i < 5; i++)
    {
        for (var j = 0; j < 5; j++)
        {
            yield return new object[] { i, j, i + j };
        }
    }
}

答案 1 :(得分:1)

您可以使用ScaffoldState关闭抽屉。只需跟踪时间,您就可以做好准备。在this的答案中,我告诉您如何在抽屉中使用ScaffoldState

此代码将帮助您实现所需的目标。我使用了上一个答案中的第二个选项,即仅使用MainPage中的所有内容

class MainPage extends StatelessWidget {
  
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  
  // this will check for the drawer state and close it
  // using _scaffoldKey
  timer() {
    return Future.delayed(Duration(seconds: 2), (){
      // checking whether it is open
      if(_scaffoldKey.currentState.isDrawerOpen){
        // here how you close it
        _scaffoldKey.currentState.openEndDrawer();
      }
    });
  }
  
  Future<void> _showMyDialog(BuildContext context) async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('AlertDialog Title'),
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Text('This is a demo alert dialog.'),
                Text('Would you like to approve of this message?'),
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Approve'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }
  
  // Our drawer
  Drawer _drawer(BuildContext context) => Drawer(
    child: RaisedButton(
      onPressed: (){
        timer();
        _showMyDialog(context);
      },
      child: Text('Show Dialog'),
    )
  );
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(),
      drawer: _drawer(context)
    );
  }
}

结果

Resultant GIF

请注意:我没有点击屏幕上的任何位置来关闭抽屉。它会自动通过timer()