Flutter Thursday 03: 制作一个有“质感”的导

2020-08-26  本文已影响0人  渣渣曦

导航是大多数app应用的重要组成方面。挑选pinterest.com的设计来完成开发

image.png
创建项目并切换目录
flutter create texty_navigation
cd texty_navigation

本文代码会完全写在lib/main.dart文件中。清除原有代码后加入以下行

import 'package:flutter/material.dart';

void main() => runApp();

应用采用材料设计时需要导入material的包。定义main(主)函数设用runApp组件启动应用。增加以下代码至runAPP组件中

MaterialApp(
      title: 'Texty Navigation',
      theme: new ThemeData(
        primaryColor: Color.fromRGBO(55, 113, 170, 1.0),
      ),
      home: new TextyNavigation(),
)

MaterialApp组件定义了应用程序使用材料设计,该组件包含两个属性:title属性用来在设备上鉴别app,theme属性定义应用程序组件的颜色。定义一个primaryColor属性,值为rgba(55,113,170,1);home属性定义app默认路由。
创建状态为statefulWidgetTextyNavigation()函数,返回Scaffold组件。

class TextyNavigation extends StatefulWidget {
  @override
  _TextyNavigationState createState() => _TextyNavigationState();
}

class _TextyNavigationState extends State<TextyNavigation> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(...);
  }
}

Scaffold继承了基本的材料设计的布局,用来创建应用的标题栏、抽屉(侧边菜单/导航),底部sheet页等。本文仅需要AppBar和抽屉。修改代码片段如下

class TextyNavigation extends StatefulWidget {
  @override
  _TextyNavigationState createState() => _TextyNavigationState();
}

class _TextyNavigationState extends State<TextyNavigation> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Texty Navigation"),
      ),
      drawer: Drawer(
        child: Container(
          decoration: BoxDecoration(color: Color.fromRGBO(55, 113, 170, 1.0)),
        ),
      ),
    );
  }
}

scaffold的AppBar组件显示水平banner在其中设置title属性值为Text("Texty Navigation")。drawer属性增加抽屉组件,默认水平显示在scaffold组左边,隐藏情况下通过滑动设备屏幕显示。Drawer中包含一个Container的子组件,通过BoxDecoration组件设置颜色。BoxDecoration被用来绘制或修饰四边形边框,如:定义边线、增加图像、绘制角度等。
运行程序如下图

image.png
上图的抽屉包含两部分:profile简介和导航项。profile包含一个照片,创建assets文件夹增加照片,打开pubspec.yaml文件,增加以下配置
flutter:
  assets:
   - image-name.png

创建makeProfileAvatar()函数供组件profile使用。

  makeProfileAvatar() {
    return Column(
      children: <Widget>[
        // SizedBox(height: 10.0),
        CircleAvatar(
          radius: 60.0,
          backgroundImage: new AssetImage('assets/shubie2.png'),
        ),
        SizedBox(height: 20.0),
        Center(
          child: new Text("Shuaib Afegbua",
              style: new TextStyle(
                  fontSize: 20.0,
                  color: Colors.white,
                  fontWeight: FontWeight.bold)),
        ),
        Center(
          child: new Text("Abuja, Nigeria",
              style: new TextStyle(
                  fontSize: 18.0,
                  color: Colors.white70,
                  fontWeight: FontWeight.normal)),
        )
      ],
    );
  }

该组件通过Column组件包含了多个组件,包括CircleAvatar用来显示简介照片,SizedBox组件用来加组件间间距,高度设为10.0,两个Center组件居中显示名字和地址。
接着创建菜单项组件,使用icon图标和文本做为参数;返回一个Column组件。

 Column makeMenuItem(icon, title) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      mainAxisSize: MainAxisSize.min,
      verticalDirection: VerticalDirection.down,
      children: <Widget>[
        Center(
            child: Icon(
          icon,
          size: 80.0,
          color: Colors.white,
        )),
        SizedBox(height: 10.0),
        new Center(
          child: new Text(title,
              style: new TextStyle(
                  fontSize: 18.0,
                  color: Colors.white,
                  fontWeight: FontWeight.bold)),
        )
      ],
    );
  }

代码相当简洁,该组件返回Children多组件:Center显示菜单图标,SizedBoxCenter组件显示菜单标签。对icon和字体设置大小尺寸。
使用Flutter有GridView组件在网格中放入菜单项。创建menuGrid()组件返回菜单项的GridView.count,代码如下:


  GridView menuGrid() {
    return GridView.count(
      crossAxisCount: 2,
      children: <Widget>[
        makeMenuItem(Icons.message, "Messages"),
        makeMenuItem(Icons.phone_forwarded, "Calls"),
        makeMenuItem(Icons.dialpad, "Dial"),
        makeMenuItem(Icons.contacts, "Contacts"),
        makeMenuItem(Icons.more_horiz, "More"),
        makeMenuItem(Icons.settings, "Settings")
      ],
    );
  }

设置crossAxisCount值为2显示两列column网络。调用makeMenuItem(Icon,text)加入Children组件中.
最后把makeProfileAvatar()menuGrid()方法加入抽屉中。修改Scaffold组件Drawer抽屉child组件为Container,Container的child为Column,Column的children中使用Expanded包含Row、Column或Flex,flex元素产生children中组件的隔离空间。如下代码


    return Scaffold(
      appBar: AppBar(
        title: Text("Texty Navigation"),
      ),
      drawer: Drawer(
        child: Container(
          padding: EdgeInsets.only(top: 60.0),
          decoration: BoxDecoration(color: Color.fromRGBO(55, 113, 170, 1.0)),
          child: Column(
            children: <Widget>[
              Expanded(
                child: makeProfileAvatar(),
                flex: 1,
              ),
              Expanded(
                child: menuGrid(),
                flex: 3,
              )
            ],
          ),
        ),
      ),
    );

保存并运行代码,如下图


image.png
上一篇下一篇

猜你喜欢

热点阅读