Flutter Drawer制作抽屉菜单

Flutter 制作一个抽屉菜单

大家好我是米卡,这次我们来讲一下如何在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),
          ),
        ],
      ),
    );
  }
}
posted @ 2020-06-13 17:29  JobsOfferings  阅读(875)  评论(0编辑  收藏  举报