【问题标题】:How to change navigation drawer hamburger menu icon to arrow icon when open/close drawer layout - Flutter?打开/关闭抽屉布局时如何将导航抽屉汉堡菜单图标更改为箭头图标 - Flutter?
【发布时间】:2019-04-25 04:13:55
【问题描述】:

当我按照Add a Drawer to a screen docs 创建抽屉布局时,它工作正常。但是,我有一个问题,这是菜单图标。

在 Android 中,我使用 DrawerToggle 设置抽屉布局,当我打开抽屉时,菜单图标将变为箭头图标,当我关闭抽屉时,箭头图标将变为菜单图标。

在 Flutter 中,它不能像上面那样工作。

如果你理解我的问题,请帮助我。我搜索了很多,但没有找到解决方案。所以想问问大家。非常感谢。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  final appTitle = 'Drawer Demo';

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

class MyHomePage extends StatelessWidget {
  final String title;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: Center(child: Text('My Page!')),
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the Drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              child: Text('Drawer Header'),
              decoration: BoxDecoration(
                color: Colors.blue,
              ),
            ),
            ListTile(
              title: Text('Item 1'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: Text('Item 2'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

标签: flutter


【解决方案1】:

使用StateFulWidget,这样你就可以访问setState方法来改变图标

在您的 state 课程中

定义一个Global Key

final GlobalKey<ScaffoldState> _key = GlobalKey();

定义一个boolean 来检查Drawer 是否打开。

bool _isDrawerOpen = false;

将这些添加到您的 state 课程中

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Title'),
        leading: IconButton(
          icon: _isDrawerOpen ? Icon(Icons.menu) : Icon(Icons.arrow_back), 
          onPressed: onPressed,
        ),
      ),
      drawer: WillPopScope(child: Drawer(), onWillPop: onPop),
      body: //body
      key: this._key,
    );
  }

void onPressed() {
  if (!_isDrawerOpen) {
    this._key.currentState.openDrawer();
  } else {
    Navigator.pop(context);
  }
  setState(() {
    _isDrawerOpen = !_isDrawerOpen;
  });
}

void onPop() {
  if (_isDrawerOpen) {
    setState(() {
      _isDrawerOpen = false;
    });
  }
  Navigator.pop(context);
} 

【讨论】:

  • 我理解你的想法。它工作得很好,虽然有一些小错误。你和@android 的代码都为我工作。非常感谢。
【解决方案2】:

在抽屉打开时更改汉堡图标并在应用栏下方显示抽屉:

我在我的代码中声明了“方法 1”和“方法 2”,它们位于 cmets 中。

“方法1”允许打开抽屉并使用抽屉控制器回调更改图标。

“方法2”允许点击汉堡图标时打开抽屉问题是如果我们使用抽屉控制器时无法点击汉堡图标。

import 'package:flutter/material.dart';

class MyNavDrawerController extends StatefulWidget {
  createState() {
    return StateKeeper();
  }
}

class StateKeeper extends State<MyNavDrawerController> {
  // Declare a new variable which will increment on FAB tap
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  final appBarColor = const Color(0xFFd2527f);
  var myIcon = new Icon(Icons.list);

  DrawerCallback drawerCallback(bool status) {
    Fluttertoast.showToast(
        msg: "Drawer " + status.toString(),
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIos: 1,
        backgroundColor: appBarColor,
        textColor: Colors.white,
        fontSize: 14.0);
    setState(() {
      setMenuIcon(status);
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      primary: true,
      appBar: AppBar(
        title: Text("Parent Scaffold"),
          leading: new IconButton(icon: myIcon,
              onPressed:(){
                _scaffoldKey.currentState.openDrawer();

              }
          )
      ),


      // METHOD 1
      /*body: DrawerController(
        child: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('Andy Rubin'),
                decoration: BoxDecoration(color: Colors.blue),
              ),
              ListTile(
                title: Text('Home'),
                onTap: () {
                  setState(() {
                    Navigator.pop(context);
                  });
                },
              ),
              ListTile(
                title: Text('About us'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "About us clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.red,
                      textColor: Colors.white,
                      fontSize: 16.0);
                },
              ),
              ListTile(
                title: Text('Notifications'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "Notifications clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.blue,
                      textColor: Colors.white,
                      fontSize: 18.0);
                },
              )
            ],
          ),
        ),
          alignment: DrawerAlignment.start, drawerCallback: drawerCallback
      ),*/


      // METHOD 2
      /*body: Scaffold(
        key: _scaffoldKey,
        drawer: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('Andy Rubin'),
                decoration: BoxDecoration(color: Colors.blue),
              ),
              ListTile(
                title: Text('Home'),
                onTap: () {
                  Fluttertoast.showToast(
                      msg: "Home clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: appBarColor,
                      textColor: Colors.white,
                      fontSize: 14.0);
                  setState(() {
                    Navigator.pop(context);
                  });
                },
              ),
              ListTile(
                title: Text('About us'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "About us clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.red,
                      textColor: Colors.white,
                      fontSize: 16.0);
                },
              ),
              ListTile(
                title: Text('Notifications'),
                onTap: () {
                  Navigator.pop(context);
                  Fluttertoast.showToast(
                      msg: "Notifications clicked! :)",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIos: 1,
                      backgroundColor: Colors.blue,
                      textColor: Colors.white,
                      fontSize: 18.0);
                },
              )
            ],
          ),
        ),
      )*/

    );
  }

  void setMenuIcon(bool isDrawerOpen){
    if(isDrawerOpen){
      myIcon = new Icon(Icons.list);
    }else{
      myIcon = new Icon(Icons.arrow_back);
    }
  }

}

【讨论】:

  • 你的解释很好,很详细。方法 1 工作正常,方法 2 有一点错误:_scaffoldKey。你和@Mangaldeep Pannu 的代码都为我工作。非常感谢。
【解决方案3】:

下面我附上我的代码的 sn-p,我认为这是拥有自定义汉堡图标的最简单方法。代码的主要部分是使用 leading:!

return Scaffold(
    backgroundColor: Colors.white,
    appBar: AppBar(
      backgroundColor: Colors.transparent,
      elevation: 0.0,
      leading: Builder(
          builder: (context) => IconButton(
                icon: Icon(
                  Icons.sort,
                  color: Colors.black54,
                ),
                onPressed: () => Scaffold.of(context).openDrawer(),
                tooltip:
                    MaterialLocalizations.of(context).openAppDrawerTooltip,
              )),
    ),
    drawer: Drawer(
      child: ListView(
        padding: EdgeInsets.zero,
        children: <Widget>[
          DrawerHeader(
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
            child: Text('App'),
          ),
          ListTile(
            title: Text('Item 1'),
            onTap: () {
              Navigator.pop(context);
            },
          ),
          ListTile(
            title: Text('Item 2'),
            onTap: () {
              Navigator.pop(context);
            },
          ),
        ],
      ),
    ),)

【讨论】:

    猜你喜欢
    • 2016-02-02
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多