flutter实战1:完成一个有侧边栏的主界面

经由2周的进修,看过笔记1-8的小伙伴们已经有不少最先本身写APP了,我也按耐不住这股热忱,想要本身开辟个APP玩玩,so,从本篇起,仿制一个APP,项目从0最先,每篇增添一些内容,一点一点完成这个APP,每次迭代的代码都将上传到我的git堆栈。

鉴于我2周多的Flutter代码履历,代码组织的头脑能够没有多年开辟履历的老鸟稳,假如有写的不好的地方请人人多多指教。

《flutter实战1:完成一个有侧边栏的主界面》

如上图所示, 本篇将搭建一个HomePage,再其左上角到场侧边栏进口,而且经由过程侧边栏能够进入其他页面。

第一步

建立项目和文件夹。翻开vscode,到一个途径下输入敕令:

flutter create appbyflutter

依据图中所示,将项目目次准备好:
《flutter实战1:完成一个有侧边栏的主界面》

由于第一篇开辟用到的东西不多,先简朴向项目目次中增加一个images文件,用于寄存APP默许图片。默许的lib文件夹下增加一个pages文件夹,用于寄存每一个页面。

第二步

main.dart仅作为APP的进口,负担页面进口和路由的功用:
《flutter实战1:完成一个有侧边栏的主界面》

由于APP不只有一个页面,为了轻易保护和治理,一切的页面代码都转移到pages文件夹下,main.dart中处置惩罚APP的主页面进口、路由和一系列须要初始化(如自动上岸、入场动画等)的使命。有过vue、react开辟履历的前端大神们应当不生疏,如许做能够使主顺序和页面解耦,固然本篇还没有用到路由,暂不誊写路由的代码,等不及要相识路由的同砚能够参考前端高手偏罗第一个APP或许英文浏览明白

第三步

主页面

如第一步的图所示,在pages文件夹中增加了2个文件:home_page.dartother_page.dart,个中home_page.dart是这个APP的主页面,other_page.dart作为的今后再开辟的页面。

注意在第二步的runapp()函数中,用到了MaterialApp(),意味着顺序APP一切的页面控件默许配套_Material_作风。

由于主页面会动态援用种种控件,因而_StatefulWidget_范例才能够满足页面需求。从下图中剖析一下页面组织:

《flutter实战1:完成一个有侧边栏的主界面》

先看图左中有状况控件HomePage为全部页面的最顶层包裹,其内放入了一个Scaffold脚手架,Scaffold中有异常丰富的属性,能够放入侧边栏按钮Drawer控件、页面题目AppBar控件和body部份,因而贴入以下代码:

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("CYC"), backgroundColor: Colors.redAccent,),  //头部的题目AppBar
      drawer: new Drawer(),  //侧边栏按钮Drawer
      body: new Center(  //中心内容部份body
        child: new Text('HomePage',style: new TextStyle(fontSize: 35.0),),
      ),
    );
  }
}

OK,左图的页面就这么轻松搭建终了。要完成右图中的睁开的侧边栏,很简朴,向Drawer控件中塞东西吧。

侧边栏

我们先图解一下侧边栏的组织:
《flutter实战1:完成一个有侧边栏的主界面》

  • 全部侧边栏主从上到下按区块离别安排了账号多少功用项+分割线的列表,很轻易想到运用规划控件ListView
  • 账号信息地区中有账号头像、粉丝头像、账号笔墨信息和背景图,这块我们能够运用Material控件库的UserAccountsDrawerHeader控件完成。
  • 下面的功用列表项目不必多说,ListTitle控件妥妥的,分割线直接Divider即可。

因而,我们向new Drawer()中到场以下代码:

//侧边栏添补内容
drawer: new Drawer(     //侧边栏按钮Drawer
        child: new ListView(
          children: <Widget>[
            new UserAccountsDrawerHeader(   //Material内置控件
              accountName: new Text('CYC'), //用户名
              accountEmail: new Text('example@126.com'),  //用户邮箱
              currentAccountPicture: new GestureDetector( //用户头像
                onTap: () => print('current user'),
                child: new CircleAvatar(    //圆形图标控件
                  backgroundImage: new NetworkImage('https://upload.jianshu.io/users/upload_avatars/7700793/dbcf94ba-9e63-4fcf-aa77-361644dd5a87?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'),//图片调取自收集
                ),
              ),
              otherAccountsPictures: <Widget>[    //粉丝头像
                new GestureDetector(    //手势探测器,能够辨认种种手势,这里只用到了onTap
                  onTap: () => print('other user'), //临时先打印一下信息吧,今后再增加跳转页面的逻辑
                  child: new CircleAvatar(
                    backgroundImage: new NetworkImage('https://upload.jianshu.io/users/upload_avatars/10878817/240ab127-e41b-496b-80d6-fc6c0c99f291?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'),
                  ),
                ),
                new GestureDetector(
                  onTap: () => print('other user'),
                  child: new CircleAvatar(
                    backgroundImage: new NetworkImage('https://upload.jianshu.io/users/upload_avatars/8346438/e3e45f12-b3c2-45a1-95ac-a608fa3b8960?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'),
                    ),
                ),
              ],
              decoration: new BoxDecoration(    //用一个BoxDecoration装潢器供应背景图片
                image: new DecorationImage(
                  fit: BoxFit.fill,
                  // image: new NetworkImage('https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/lakes/images/lake.jpg')
                  //能够尝尝图片调取自当地。挪用当地资本,须要到pubspec.yaml中配置文件途径
                  image: new ExactAssetImage('images/lake.jpg'),
                ),
              ),
            ),
            new ListTile(   //第一个功用项
              title: new Text('First Page'),
              trailing: new Icon(Icons.arrow_upward),
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new SidebarPage()));
              }
            ),
            new ListTile(   //第二个功用项
              title: new Text('Second Page'),
              trailing: new Icon(Icons.arrow_right),
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new SidebarPage()));
              } 
            ),
            new ListTile(   //第二个功用项
              title: new Text('Second Page'),
              trailing: new Icon(Icons.arrow_right),
              onTap: () {
                Navigator.of(context).pop();
                Navigator.of(context).pushNamed('/a');
              } 
            ),
            new Divider(),    //分割线控件
            new ListTile(   //退出按钮
              title: new Text('Close'),
              trailing: new Icon(Icons.cancel),
              onTap: () => Navigator.of(context).pop(),   //点击后收起侧边栏
            ),
          ],
        ),
      )

上面的代码,用到了许多生疏的控件,如UserAccountsDrawerHeaderGestureDetectorBoxDecorationNetworkImageExactAssetImage等等,这里我就不逐一引见了,各自的特征和用法请参考官方浏览明白题库,刚最先我也是懵逼的,这些内置控件人人简朴背诵一下即可,有能够背面由于页面庞杂度的进步,零丁拿出来封装也说不定,会运用就能够了。

人人能够尝尝从屏幕的左边缘向右滑动的手势,是否是发明能够拉出侧边栏?再向右滑动收回侧边栏。我并没有增加任何手势事宜的代码,这是
Drawer控件自带的属性,和控件自带
Material作风动效一样,内置控件也自带了默许手势,隐约听到~原生开辟的顺序员哭晕在茅厕,哈哈哈

第四步

功用按钮触发页面跳转。

起首我们要建立一个子页面,因而乎pages文件夹下,我又建立了一个other_page.dart文件。要从HomePage.dart中跳转到other_page.dart,还须要在HomePage.dart中引一下other_page.dart。因而:
《flutter实战1:完成一个有侧边栏的主界面》

然后到other_page.dart中敲入代码:

import 'package:flutter/material.dart';

class OtherPage extends StatelessWidget {

  final String pageText;    //定义一个常量,用于保留跳转进来猎取到的参数

  OtherPage(this.pageText);    //组织函数,猎取参数

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text(pageText),),    //将参数看成页面题目
      body: new Center(
        child: new Text('pageText'),
      ),
    );
  }
}

Flutter请求转入的页面必需提早定义一个常量分派好空间,且在组织函数中植入这个参数,才可捕获外部传过来的参数值。

触发跳转

First PageSecond Page这两个ListTile控件中到场点击跳转页面的代码:

new ListTile(
    title: new Text('First Page'),
    trailing: new Icon(Icons.arrow_upward),
    onTap: () {
        Navigator.of(context).pop();  //点击后收起侧边栏
        Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new OtherPage('First Page')));  //进入OtherPage页面,传入参数First Page
        }
 ),
new ListTile(
    title: new Text('Second Page'),
    trailing: new Icon(Icons.arrow_right),
    onTap: () {
        Navigator.of(context).pop();
        Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new OtherPage('Second Page')));
    } 
 ),

上面的代码中onTap()事宜里有一句Navigator.of(context).pop(); ,意味着先收起侧边栏,再进入新页面。假如没有这句代码,纵然进入了新页面,再返返来,侧边栏依旧处于睁开的模样,这个体验是反人类的,所以写上它吧~少年。

总结

由于我没有细致的去定位和设想产物究竟是干什么的,人人能够会以为有点懵逼,为何是这类侧边栏的规划,而不是许多交际APP经常使用的顶部+底部Tab栏的款式,不着急,我们下一篇完成。侧边栏有什么优点呢?节约空间,假如底部须要安排更重要的功用控件(比方音乐播放器)时,往侧边栏放入页面切换逻辑是个不错的应对计划。本篇内容实在异常简朴,重要就是引见人人熟悉几个经常使用控件,不必调CSS,不必思索由于冒泡事宜致使庞杂的交互逻辑完成,这就是Flutter的魅力,简约而不简朴,置信人人看过以后,自行开辟APP的自信心更足了,好勒,本日就到这里,感谢人人的支撑,请关注我的Flutter圈子,多多投稿,也能够到场flutter 中文社区(官方QQ群:338252156)配合生长,感谢人人~

    原文作者:燃烧的鱼丸
    原文地址: https://segmentfault.com/a/1190000013805778
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞