avatar

cooyue

博客网站 - COOYUE

  • 首页
  • 友链
主页 Flutter Drawer 制作抽屉菜单
文章

Flutter Drawer 制作抽屉菜单

发表于 2020-06-12 更新于 2024-06- 7
作者 Administrator
26~33 分钟 阅读

Flutter Drawer 制作抽屉菜单

大家好我是米卡,这次我们来讲一下如何在Flutter中制作一个抽屉菜单吧~

什么是抽屉菜单呢?

  其实在APP中,抽屉菜单就是当手指在屏幕横向滑动时候,左边屏幕会滑出或者滑入一个View的东西,就像一个抽屉。下面是我在网上找的一个示例图,和现在正跑在我的模拟器上的目标图。

示例图
示例图
目标图
目标图

  在Android或者IOS上,要实现这种侧滑抽屉空间,可以使用外部库来达到效果,不过Flutter本身已经给我们提供了 Drawer 这个UI组件,来使你更轻松地达到这个效果。

Drawer及UserAccountsDrawerHeader可用属性

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

实现

  首先我默认大家已经搭建好了Flutter的环境并已经初步写了一个简单的Widget => Home用于容纳我们的布局

import 'package:coco/components/drawer.dart';
import 'package:flutter/material.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Coco',
      debugShowCheckedModeBanner: false,
      initialRoute: '/',
      routes: {
        '/': (context) => HomeIn(),
      },
      theme: ThemeData(
        primarySwatch: Colors.blue,
        highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
        splashColor: Colors.white70,
        accentColor: Color.fromRGBO(178, 222, 225, 1.0),
      ),
    );
  }
}

class HomeIn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Home();
  }
}

class Home extends StatefulWidget {
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 4,
      child: Scaffold(
          drawer: DrawerHead() // 抽取控件
        ),
    );
  }
}

  在展示的这段代码中,除与抽屉菜单无关的代码博主都已去除,以免影响同学们的阅读,这段代码可以允许运行在你的工程的lib下的main.dart中,但要注意lib文件夹内还有一个components文件夹,其下存在drawer.dart文件(抽取出来的抽屉控件)。

文件结构

...
/android
/ios
/lib
    /components
        drawer.dart
    main.dart

  main.dart中,保留了注释的地方就是我们抽出来的drawer控件,这里讲个题外话,Flutter的写法和我们前端写UI的方式是两种方法,Flutter本身是一个APP上的开源UI工具包,意思是书写它你需要使用它本身的API控件去写,这会很容易导致嵌套地狱,在Flutter中你经常能够看到向右的金字塔状代码。但是这其实也是Flutter给我们带来的信息:希望你能将你的代码保持足够的细度,这有助于你减少嵌套层数,也可以提醒你及时考虑组件的抽取以及复用,抽取的这方面就不用赘述了,相信大家都有足够的经验与习惯来处理,我们回到正题。

  事实上,在Scaffold中使用了drawer后,里面的内容(或者说Widget)就已经是以一个抽屉控件的形式展示了,大家可以试着只在darwer.dart文件中返回一个Text('jobs')来查看会出现的样子,那么我们接下来要做的只是让这个Widget更加像一个抽屉组件而已。

  为了避免可能冗余的文字描述,关于这一段的注释我已经全部打在了上面,方便大家学习。

drawer.dart

import 'package:flutter/material.dart';

class DrawerHead extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer( // 重要的Drawer组件
      child: ListView( // Flutter 可滚动组件
        padding: EdgeInsets.zero, // padding为0
        children: <Widget>[
          UserAccountsDrawerHeader( 
            // UserAccountsDrawerHeader 可以设置用户头像、用户名、Email 等信息,显示一个符合纸墨设计规范的 drawer header。
            // 标题
            accountName: Text('Jobsofferings',
                style: TextStyle(fontWeight: FontWeight.bold)),
            // 副标题
            accountEmail: Text('https://juejin.im/user/3350967174571143'),
            // Emails
            currentAccountPicture: CircleAvatar(
                // 使用网络加载图像
                backgroundImage: NetworkImage(
                  'https://images.cnblogs.com/cnblogs_com/JobsOfferings/1363202/o_preview.jpg'),
            ),
            // 圆角头像
            decoration: BoxDecoration(
                color: Colors.yellow[400],
                image: DecorationImage(
                    image: NetworkImage(
                        'http://pic.netbian.com/uploads/allimg/190510/221228-15574975489aa1.jpg'),
                    fit: BoxFit.cover, // 一种图像的布局方式
                    colorFilter: ColorFilter.mode(
                        Colors.grey[400].withOpacity(0.6),
                        BlendMode.hardLight))),
            //  BoxDecoration 用于制作背景
          ),
          // ListTile是下方的几个可点按List
          ListTile(
            // List标题
            title: Text('details', textAlign: TextAlign.right),
            trailing: Icon(
              Icons.favorite, // Icon种类
              color: Colors.black12, // Icon颜色
              size: 22.0, // Icon大小
            ),
            // 点按时间,这里可以做你想做的事情,如跳转、判断等等
            // 此处博主只使用了 Navigator.pop(context) 来手动关闭Drawer
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: Text('Favorite', textAlign: TextAlign.right),
            trailing: Icon(
              Icons.favorite,
              color: Colors.black12,
              size: 22.0,
            ),
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: Text('Settings', textAlign: TextAlign.right),
            trailing: Icon(
              Icons.favorite,
              color: Colors.black12,
              size: 22.0,
            ),
            onTap: () => Navigator.pop(context),
          ),
        ],
      ),
    );
  }
}
前端
Flutter
许可协议:  CC BY 4.0
分享

相关文章

1月 3, 2025

Nextjs 实现国际化翻译 - App Router 模式解决方案

Nextjs 实现国际化翻译 - App Router 模式解决方案 老板:最近我们网站想部署到国外去啊,我们加一个国际化翻译的功能,O 不 OK? 我:接一下谷歌翻译嘛,啪的一下,很快嗷! 老板:忘了说了,这个翻译最好能自己配置、没有配置文件的话需要兜底、变量插值,如果可以的话,页面的 title

8月 13, 2023

通过 Node 中间层,实现后端微服务架构中的服务发现和负载均衡

通过 Node 中间层,实现后端微服务架构中的服务发现和负载均衡 要详细解释服务发现和负载均衡的意义,首先我们一定要从从「什么是微服务」,以及「微服务架构的意义」开始讲起 什么是微服务? 微服务架构是一种软件架构风格,它将一个大型的、复杂的应用程序,拆分成多组小型的、独立的服务单元,这些服务单元可以

8月 9, 2023

三年初心,前端之路:从实习到负责人,我的成长与探索

三年初心,前端之路:从实习到负责人,我的成长与探索 按 20 年入职开始算的话,目前的公司差不多已经待了三年吧,现在已经毕业两年多了,自从 21 年原来的负责人离职后,就一直作为这边的基础设施组的前端 owner,一直带着两三个实习转正的同学负责目前公司的 CICD 平台和一些公司前端的基础建设。这

下一篇

使用 React hooks 转化 class 的一些思考

上一篇

node 实现登录状态持久化

最近更新

  • Nextjs 实现国际化翻译 - App Router 模式解决方案
  • 通过 Node 中间层,实现后端微服务架构中的服务发现和负载均衡
  • 三年初心,前端之路:从实习到负责人,我的成长与探索
  • 记录一次前端做请求负载处理的思考
  • 从零开始教你使用 storybook + rollup 搭建一个属于自己的 React UI 组件库

热门标签

工程 Flutter React JavaScript 面经 前端 负载均衡

目录

©2026 cooyue. 保留部分权利。

使用 Halo 主题 Chirpy