利用Flutter写一个跨平台的果核APP(1)——界面篇1

前言

从这里开始,我就准备边学边作边用博客记录下本身的重构历程,会结合已有的app的样式进行重构。bash

原图

先看一下app的截图: app

首页
左侧菜单栏
上面两个截图是app的首页和左侧菜单栏的截图,首页下方是一个能够滑动的tab+viewpager,左侧菜单栏是一个drawerlayout。

目标图像

这是实现的效果图 ide

效果图1
效果图2
接下来将会逐一分析界面并给出代码。

解析

首先咱们要作的就是划分好界面层次,这一步操做仍是很简单的,我直接贴出来目前的页面层次结构 ui

在flutter中,一切都是widget,也就是说所见的都是控件,一个空间就是一个类,一个类能够放在一个dart文件里面,也就是说能够理解为一个控件就是一个dart文件。在这里项目目录分级为以下几个部分:
TIM图片20180913195254.png

lib为存放dart文件的地方 common文件夹用于存放app执行所须要的文件 pages文件夹用于存放页面文件 pages/main存放的是首页的页面文件 pages/school存放的是校园部分的页面文件 main.dart是首页的页面文件 app.dart是整个app的入口文件this

入口文件

入口文件很简单,直接上代码spa

import 'package:flutter/material.dart';
import 'package:flutter_guohe/pages/main.dart';

void main() {
  runApp(new Guohe());
}

复制代码

底部tabbar的实现

从以前的层次图就能够看出,tabbar控制着3个页面,因此他应该是首页的顶级元素,在main.dart中添加以下代码,具体参考《Flutter底部导航栏的实现》3d

/**
 * APP的主入口文件
 */

import 'package:flutter/material.dart';

import 'package:flutter_guohe/pages/main/today.dart';
import 'package:flutter_guohe/pages/main/playground.dart';
import 'package:flutter_guohe/pages/main/kb.dart';
import 'package:flutter_guohe/pages/main/leftmenu.dart';

import 'package:flutter_guohe/common/eventBus.dart';

//果核的主界面
class Guohe extends StatefulWidget {
  @override
  GuoheState createState() => new GuoheState();
}

class GuoheState extends State<Guohe> with SingleTickerProviderStateMixin {
  TabController controller;
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  void initState() {
    controller = new TabController(length: 3, vsync: this);
    eventBus.on<EventOpenDrawer>().listen((EventOpenDrawer data) {
      if (data.flag) _scaffoldKey.currentState.openDrawer();
    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        key: _scaffoldKey,
        drawer: new LeftMenu(),
        body: new TabBarView(
          controller: controller,
          children: <Widget>[
            new Today(),
            new Kb(),
            new Playground(),
          ],
        ),
        bottomNavigationBar: new Material(
          color: Colors.white,
          child: new TabBar(
            controller: controller,
            labelColor: Colors.deepPurpleAccent,
            unselectedLabelColor: Colors.black26,
            tabs: <Widget>[
              new Tab(
                text: "今日",
                icon: new Icon(Icons.brightness_5),
              ),
              new Tab(
                text: "课表",
                icon: new Icon(Icons.map),
              ),
              new Tab(
                text: "操场",
                icon: new Icon(Icons.directions_run),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
复制代码

左侧菜单栏

左侧菜单栏就是一个drawer,就是一个抽屉,在Scaffold中申明就行了,在这里我为了看起来不那么乱,建立了一个leftmenu.dart文件用来展现左侧菜单界面,只要知道了row、column、padding的用法就能够很快的写出来了,参考《flutter实战1:完成一个有侧边栏的主界面》。下面贴代码code

import 'package:flutter/material.dart';

//左侧菜单栏
class LeftMenu extends Drawer {
  @override
  Widget build(BuildContext context) {
    return new Drawer(
      //侧边栏按钮Drawer
      child: new ListView(
        children: <Widget>[
          //我的信息部分
          new Container(
              color: Color.fromARGB(255, 119, 136, 213),
              child: new Padding(
                padding: new EdgeInsets.all(26.0),
                child: new Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    new Row(
                      children: <Widget>[
                        //头像
                        new Container(
                          width: 80.0,
                          height: 80.0,
                          margin:
                              new EdgeInsets.only(right: 10.0, bottom: 15.0),
                          decoration: BoxDecoration(
                            image: DecorationImage(
                              image: new NetworkImage(
                                  'http://www.chedan5.com/upload/article/201803/06/1740235a9e62077e0aexbcUQh.jpg'),
                              //从Assets加载图片
                              fit: BoxFit.cover,
                            ),
                            shape: BoxShape.circle,
                          ),
                        ),
                        new Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            new Text(
                              '梁越勇',
                              style: new TextStyle(
                                  color: Colors.white, fontSize: 25.0),
                            ),
                            new Text(
                              '152210702112',
                              style: new TextStyle(
                                  color: Colors.white, fontSize: 15.0),
                            )
                          ],
                        )
                      ],
                    ),
                    new Text(
                      "计算机学院",
                      style: new TextStyle(color: Colors.white, fontSize: 18.0),
                    )
                  ],
                ),
              )),
          new ListTile(
              //第二个功能项
              title: new Text('关于咱们'),
              leading: new Icon(Icons.accessibility),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("关于咱们"),
                    ));
              }),
          //分割线控件
          new ListTile(
              //退出按钮
              title: new Text('分享此应用'),
              leading: new Icon(Icons.share),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("分享此应用"),
                    ));
              } //点击后收起侧边栏
              ),
          //分割线控件
          new ListTile(
              //退出按钮
              title: new Text('给咱们反馈'),
              leading: new Icon(Icons.feedback),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("给咱们反馈"),
                    ));
              } //点击后收起侧边栏
              ),
          //分割线控件
          new ListTile(
              //退出按钮
              title: new Text('联系开发者'),
              leading: new Icon(Icons.flight),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("联系开发者"),
                    ));
              } //点击后收起侧边栏
              ),
          //分割线控件
          new ListTile(
              //退出按钮
              title: new Text('加入交流群'),
              leading: new Icon(Icons.group_add),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("加入交流群"),
                    ));
              } //点击后收起侧边栏
              ),
          new ListTile(
              //退出按钮
              title: new Text('切换帐号'),
              leading: new Icon(Icons.sync),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("切换帐号"),
                    ));
              } //点击后收起侧边栏
              ),
          new ListTile(
              //退出按钮
              title: new Text('检测升级'),
              leading: new Icon(Icons.refresh),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("检测升级"),
                    ));
              } //点击后收起侧边栏
              ),
          new ListTile(
              //退出按钮
              title: new Text('更新说明'),
              leading: new Icon(Icons.info),
              onTap: () {
                Navigator.of(context).pop();
                Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("更新说明"),
                    ));
              } //点击后收起侧边栏
              ),
        ],
      ),
    );
  }
}
复制代码