前言

平时开发中难免会碰到抽屉效果,如果自己写肯定要费一番工夫,用别人的也要付出代码量,Scaffold实际上已经默认提供了 Drawer 抽屉效果供我们使用,下面我们就看看怎么使用的吧

先上一张效果图

demo案例

Drawer 与 UserAccountsDrawerHeader

Drawer就是我们的抽屉效果,而 UserAccountsDrawerHeader就是我们侧边栏上面的那片用户信息页面,可有可无,为了方便可以使用,当然也可以自己定制

下面直接上一个属性表格,方便理解, UserAccountsDrawerHeader从属性就可以看到功能比较固定,可以看情况使用

Drawer属性 说明
elevation 背景高度
child 子组件
semanticLabel 标签
width 侧边栏宽度
UserAccountsDrawerHeader属性 说明
decoration 头部装饰
margin 外边距  默认8.0
currentAccountPicture 主图像
otherAccountsPictures 副图像
accountName 标题
accountEmail 副标题
onDetailsPressed 点击监听

话不多说,直接上代码

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text("首页"),
    ),
    body: const Center(
      child: Text("我是首页内容"),
    ),
    //endDrawer: Container(), //是右边侧边栏不多说了
    //我们就在这里面直接写了,使用默认的 Drawer 就是抽屉效果了
    drawer: Drawer(
      child: ListView(
        padding: const EdgeInsets.all(0),
        children: const <Widget>[
          //侧边栏顶部效果,可以根据情况使用,可有可无
          UserAccountsDrawerHeader(
            accountName: Text("标题"),
            accountEmail: Text("副标题"),
            //头像
            currentAccountPicture: CircleAvatar(
              backgroundColor: Colors.white,
            ),
            //背景
            decoration: BoxDecoration(color: Colors.blue),
          ),
          ListTile(title: Text("item0..."),),
          ListTile(title: Text("item1..."),),
          ListTile(title: Text("item2..."),),
        ],
      ),
    ),
  );
}

侧边栏这样就介绍完毕了。

读者:这就完了?根本不够用,感觉侧边栏按钮跟自己的不太一样,想换一个首页唤出侧边栏的按钮?

尝试案例后,就会知道,其实上面的案例图就是换过的侧边栏按钮,变粗了一点,没错,这也和我们后面介绍的 Builder 关联上了

定制唤出按钮并引出 Builder 组件

实际上我们定制侧边栏的时候,只需要更换 AppBarleading 即可,Scaffold 默认提供了 openDrawer 方法打开或者关闭侧边栏,下面就距离打开侧边栏

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text("首页"),
      // leading: const Leading(),//直接写成小组件可以解决从context查找父类引起的bug
      leading: IconButton(
        onPressed: () {
          Scaffold.of(context).openDrawer();
          //Scaffold.of(context).closeDrawer(); //关闭侧边栏
          // Scaffold.of(context).openEndDrawer();//打开右侧侧边栏
        },
        icon: const Icon(Icons.table_rows_rounded),
        iconSize: 20,
      );
      ),
    ),
    body: const Center(
      child: Text("我是首页内容"),
    ),
    //我们就在这里面直接写了
    drawer: Drawer(
       ...
    ),
  );
}

问题

看了上面的说法和案例,那么可能会碰到一个 Bug,就是找不到 Scaffold,或者无法开关 Drawer,问题在于 Scaffold.of

Scaffold.of(context)

其会像向父类查找该组件,此时我们传递的,context,从哪里来的,看上面的代码就知道,是从当前Build中传递过来的 context,其祖先是谁,是我们的 MaterialApp,因此会出现找不到 Scaffold 或者无法打开侧边栏的问题

//根据context到 父类祖先中查找状态
final ScaffoldState? result = context.findAncestorStateOfType&lt;ScaffoldState&gt;();
if (result != null) {
  return result;
}

解决方案

外面嵌套一个 Builder即可, Builder实际上是一个 StatelessWidget小组件,其就是参数 builder就是利用回调带回了自己的 context从而解决的 context 父类查找问题

因此,我们将 Leading 的按钮换成一个 StatelessWidget,也可以作为其中一个解决方案,不过,我相信很多人更愿意选择 Builder IconButton,毕竟其就只有一个按钮,这也是一些系统或者三方组件经常使用 Builder的原因了吧

Builder(
  builder: (context) {
    return IconButton(
      onPressed: () {
        //会从context的父类开始找组件context.findAncestorStateOfType
        //当前组件的context父组件是 MyApp 是没有 Scaffold,且没有drawer,因此无法打开
        //Builder是一个StatelessWidget基础组件,只不过返回了自己的context,因此没问题
        Scaffold.of(context).openDrawer();
        //Scaffold.of(context).closeDrawer(); //关闭侧边栏
        // Scaffold.of(context).openEndDrawer();//打开右侧侧边栏
      },
      icon: const Icon(Icons.table_rows_rounded),
      iconSize: 20,
    );
  },
),

整体代码

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);
  @override
  State<HomePage> createState() => _HomePageState();
}
//小组件
class Leading extends StatelessWidget {
  const Leading({
    Key? key,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return IconButton(
      onPressed: () {
        Scaffold.of(context).openDrawer();
      },
      icon: const Icon(Icons.table_rows_rounded),
      iconSize: 20,
    );
  }
}
class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("首页"),
        // leading: const Leading(),//直接写成小组件可以解决从context查找父类引起的bug
        leading: Builder(
          builder: (context) {
            return IconButton(
              onPressed: () {
                //会从context的父类开始找组件context.findAncestorStateOfType
                //当前组件的context父组件是 MyApp 是没有 Scaffold,且没有drawer,因此无法打开
                //Builder是一个StatelessWidget基础组件,只不过返回了自己的context,因此没问题
                Scaffold.of(context).openDrawer();
                //Scaffold.of(context).closeDrawer(); //关闭侧边栏
                // Scaffold.of(context).openEndDrawer();//打开右侧侧边栏
              },
              icon: const Icon(Icons.table_rows_rounded),
              iconSize: 20,
            );
          },
        ),
      ),
      body: const Center(
        child: Text("我是首页内容"),
      ),
      //endDrawer: Container(), //是右边侧边栏不多说了
      //我们就在这里面直接写了
      drawer: Drawer(
        child: ListView(
          padding: const EdgeInsets.all(0),
          children: const <Widget>[
            UserAccountsDrawerHeader(
              accountEmail: Text("副标题"),
              accountName: Text("标题"),
              //头像
              currentAccountPicture: CircleAvatar(
                backgroundColor: Colors.white,
              ),
              //背景
              decoration: BoxDecoration(color: Colors.blue),
            ),
            ListTile(title: Text("item0..."),),
            ListTile(title: Text("item1..."),),
            ListTile(title: Text("item2..."),),
          ],
        ),
      ),
    );
  }
}

最后

快来尝试一下吧,相信,马上就能用个明明白白,我也是在使用其的过程中,发现了 Scaffold.of查找的逻辑问题,进而进出 Builder来解决问题,相信里面还有不少用到 Builder的组件有类似的情况,那时候就不一定是 scaffold.of 了😂

以上就是Drawer Builder组件实现flutter侧边抽屉效果示例分析的详细内容,更多关于Drawer Builder flutter侧边抽屉的资料请关注Devmax其它相关文章!

Drawer Builder组件实现flutter侧边抽屉效果示例分析的更多相关文章

  1. Flutter中文教程-Cookbook

    Flutter中文网的Cookbook中包含了在编写Flutter应用程序时常见问题及示例。设计基础使用主题共享颜色和字体样式Images显示来自网上的图片用占位符淡入图片使用缓存图Lists创建一个基本list创建一个水平list使用长列表创建不同类型子项的List创建一个gridList处理手势处理点击添加Material触摸水波效果实现滑动关闭导航导航到新页面并返回给新页面传值从新页面返回数据给上一个页面网络从网上获取数据进行认证请求使用WebSockets

  2. android-studio – 未配置Dart SDK

    Initializinggradle…

  3. 安卓 – 从一个扑动的应用程序拨打电话

    或者有更好的选择从我的应用程序拨打电话?

  4. android – 如何在Flutter中添加Webview?

    我知道可以将WebView添加为整页,但找不到任何示例代码.我假设你可以使用PageView作为它的基础,但不知道如何调用本机androidWebView并将其添加到PageView.谁能指出我正确的方向?

  5. android – 如何将消息从Flutter传递给Native?

    如果需要与特定的API/硬件组件进行交互,您如何将Flutter的信息传递回Android/Native代码?是否有任何事件频道可以通过其他方式发送信息或类似于回调?

  6. android – 如何在Flutter App中处理onPause / onResume?

    我是否过于复杂的事情?即使我的用例似乎不需要它,我仍然想知道:如何自己处理onPause/onResume事件?

  7. android – 如何使用Flutter构建Augment Reality应用程序?

    我对Android开发有一些基础知识.最近听说过Flutter并且非常有兴趣研究它.我想知道是否有可能使用颤振构建增强现实应用程序以及要实现此目的的方法?请帮忙.解决方法截至目前,颤振不支持3D.Flutter现在专注于2D,团队长期计划为颤振提供优化的3Dapi.你读了常见问题here.

  8. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. Flutter StreamBuilder实现局部刷新实例详解

    这篇文章主要为大家介绍了Flutter StreamBuilder实现局部刷新实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. Flutter 首页必用组件NestedScrollView的示例详解

    今天介绍的组件是NestedScrollView,大部分的App首页都会用到这个组件。对Flutter 首页必用组件NestedScrollView的相关知识感兴趣的一起看看吧

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部