【问题标题】:Drawer Works only with AppBar but does not with with Custom App BarDrawer 仅适用于 AppBar,但不适用于自定义 App Bar
【发布时间】:2021-02-12 20:55:30
【问题描述】:

我正在尝试创建一个抽屉..

我正在定制每一件事,所以我创建了一个自定义脚手架,如下代码:

import 'package:flutter/material.dart';
import 'package:ipet/constants/constants.dart';

class IPetCustomScaffold extends StatelessWidget {
  final Widget body;
  final PreferredSizeWidget iPetTopAppBar;
  final PreferredSizeWidget iPetBottomAppBar;
  final Key ipKey;
  final Color iPetBGScaffoldColor;
  final Widget iPetDrawer;

  const IPetCustomScaffold({
    @required this.body,
    this.ipKey,
    @required this.iPetTopAppBar,
    this.iPetBottomAppBar,
    this.iPetBGScaffoldColor = AppConst.kPrimaryWhiteBgColor,
    this.iPetDrawer,
  });

  @override
  Scaffold build(BuildContext context) {
    return Scaffold(
      backgroundColor: iPetBGScaffoldColor,
      key: ipKey,
      appBar: iPetTopAppBar,
      body: SafeArea(
        child: body,
      ),
      bottomNavigationBar: iPetBottomAppBar,
      drawer: iPetDrawer,
    );
  }
}

我有一个自定义 AppBar,如下代码:

import 'package:flutter/material.dart';
import 'package:ipet/constants/ipet_dimens.dart';

class IPetCustomTopBarWidget extends StatelessWidget
    implements PreferredSizeWidget {
  final String iPetPawImage;
  final double iPetIconSize;
  final IconData iPetListIconData;
  final Widget iPetFirstPart;
  final List<Widget> iPetMiddlePart;
  final List<Widget> iPetLastPart;

  @override
  final Size preferredSize;

  IPetCustomTopBarWidget({
    this.iPetIconSize = IPetDimens.space20,
    this.iPetListIconData,
    this.iPetPawImage,
    @required this.iPetFirstPart,
    @required this.iPetMiddlePart,
    this.iPetLastPart,
  }) : preferredSize = Size.fromHeight(IPetDimens.space60);

  ShapeBorder kBackButtonShape = RoundedRectangleBorder(
    borderRadius: BorderRadius.only(
      topRight: Radius.circular(IPetDimens.space30),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Row(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: IPetDimens.space15),
            child: iPetFirstPart,
          ),
          Expanded(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: iPetMiddlePart,
            ),
          ),
          Row(
            children: iPetLastPart,
          ),
        ],
      ),
    );
  }
}

现在我需要在我的仪表板页面中创建一个抽屉:

Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return IPetCustomScaffold(
       iPetTopAppBar: IPetCustomTopBarWidget(
         iPetMiddlePart: [
           DefaultImage(
             image: 'assets/images/ipet_paw_img.png',
           ),
           Label(
             text: 'Settings',
           ),
         ],
         iPetLastPart: [],
       ),      
       iPetDrawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough ver tical
        // 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);
              },
            ),
          ],
        ),
      ),
      body: ...
);

现在的问题是抽屉不适用于此自定义应用栏,仅适用于普通 AppBar() 作为默认小部件,AppBar 的结果如下图所示

这是使用自定义应用栏时的结果

我可能使用了错误的技术,但我希望有人推荐一个好的建议:D

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    你可以在任何你想打开抽屉的地方使用这条线:

    Scaffold.of(context).openDrawer();
    

    编辑

    当您使用自定义的时,您必须为 Scaffold 分配一个键来区分哪个脚手架应该打开抽屉

    final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
    

    然后将这个 Key 放入 Scaffold 之后,在您想以编程方式打开抽屉时调用它:

    _scaffoldKey.currentState.openDrawer();
    

    【讨论】:

    • 感谢您的支持我尝试使用此代码iPetFirstPart: MyCustomCard( colour: Colors.transparent, childCard: IPetCustomIcon(ipFontIc: FontAwesomeIcons.list), myOnTap: () { Scaffold.of(context).openDrawer(); }, ), 但仍然无法正常工作:(,我认为我的自定义脚手架的键有问题
    • 通过添加这个键final GlobalKey&lt;ScaffoldState&gt; _scaffoldKey = new GlobalKey&lt;ScaffoldState&gt;();然后把它放在我的脚手架参数中然后打开抽屉作为这个代码_scaffoldKey.currentState.openDrawer()
    • @MahmoudHarooney 是的,感谢您的添加,每当您因为编译器不知道要调用哪个脚手架而在调用脚手架时发现问题时,您必须为其分配一个键作为您编辑的答案,谢谢澄清
    • 是的,这正是我将密钥放在自定义脚手架中以分配我创建的脚手架的原因,我也可能将全局放在一个文件中的常量中以便从任何地方访问它:),谢谢你的支持! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2011-02-14
    • 1970-01-01
    • 2020-08-31
    相关资源
    最近更新 更多