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/5eaee21f5188256da0323bf9'),
            // 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),
          ),
        ],
      ),
    );
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值