利用Flutter寫一個跨平臺的果核APP(2)——界面篇2

前言

緊接上篇文章《利用Flutter寫一個跨平臺的果核APP(1)——界面篇1》 上篇文章只是將界面的基本框架搭了出來,這篇文章着手實現首頁的界面。先來看預覽圖: android

Screenshot_2018-09-14-18-48-09-649_com.lyy.guohe.png
這是此次實現的結果圖:

解析

按照圖像的分割線,我將整個首頁分割成頭部、今日課表部分、消息部分和日知錄部分跨域

  1. 首先是首頁的最外層框架部分
@override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          leading: new IconButton(
            icon: Icon(Icons.home),
            onPressed: () {
              //打開drawer
              openDrawer();
            },
          ),
          title: new Text("今日"), //設置標題內容
          backgroundColor: Color.fromARGB(255, 119, 136, 213), //設置appbar背景顏色
          centerTitle: true, //設置標題是否局中
        ),
        body: new ListView(
          children: <Widget>[
            new Header(),     //頭部
            new BigDivider(),
            new TodayKb(),    //今日課表
            new BigDivider(),
            new Message(),    //消息
            new BigDivider(),
            new One()         //日知錄
          ],
        ),
      ),
    );
  }
複製代碼

由於首頁佈局較長,因此我選擇用了一個ListView將一些控件包裹住,這裏的ListView的做用就和android中的Scrollview的做用是同樣的。BigDivider類是爲了彌補Divider類空閒過小的不足自定義的一個view,我將這個view寫在views/customview.dart裏面了,因此須要在開頭引入bash

import 'package:flutter_guohe/views/customview.dart';
複製代碼

customview.dart中的BigDivider類app

import 'package:flutter/material.dart';

//分隔欄
class BigDivider extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new SizedBox(
      height: 5.0,
      child: new Center(
        child: new Container(
          height: 5.0,
          color: Colors.black12,
        ),
      ),
    );
  }
}
複製代碼

剩下的就是依次實現上述的幾個類,熟練使用Padding/Column/Row/Container等佈局便可,在這裏有3個點須要提一下:框架

  1. 圖片資源的引用
  2. 均分佈局的實現
  3. 利用EventBus實現子控件控制父控件

對於第一個,其實官方文檔裏有介紹《資源與圖像》,可是文檔裏寫的並無說明assets文件夾存放的路徑,在這裏說明一下,assets文件夾是和lib文件夾同級的,即less

assets文件夾存放的路徑
若是想要引用assets文件夾中的路徑,須要先在 pubspec.yaml文件中添加資源文件的依賴,以下所示:
添加依賴
使用的話只須要執行

new AssetImage('assets/imgs/ic_menu_score.png'),
複製代碼

代碼便可引用該資源文件。ide

第二個 佈局

頭部圖標均分
這裏很明顯是一個Row裏面包含5個Column佈局,並且這5個Column是均分整個Row的,怎麼實現均分了,用一個Expanded()包住一個Column,而後設置其flex爲1便可,這個屬性就相似安卓裏面的 layout_weight,這樣的話理解起來就不難了

第三個的使用場景是這樣的: flex

AppBar左上角有一個IconButton,點擊該IconButton彈出Drawer,可是因爲該AppBar和Drawer並非處在同一個頁面中(AppBar在today.dart文件,Drawer在app.dart文件裏),因此如何跨域調用這個openDrawer()這個方法便成爲了一個難題,這裏推薦使用 EventBus方式,具體如何操做推薦閱讀 《flutter基礎-組件通訊(父子、兄弟)》,在這種狀況下 DrawerIconButton屬於兄弟組件。

完整代碼

today.dartui

import 'package:flutter/material.dart';
import 'package:flutter_guohe/common/eventBus.dart';
import 'package:flutter_guohe/views/customview.dart';

class Today extends StatefulWidget {
  @override
  TodayState createState() => new TodayState();
}

class TodayState extends State<Today> {
  //打開drawer
  void openDrawer() {
    eventBus.fire(new EventOpenDrawer(true));
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          leading: new IconButton(
            icon: Icon(Icons.home),
            onPressed: () {
              //打開drawer
              openDrawer();
            },
          ),
          title: new Text("今日"), //設置標題內容
          backgroundColor: Color.fromARGB(255, 119, 136, 213), //設置appbar背景顏色
          centerTitle: true, //設置標題是否局中
        ),
        body: new ListView(
          children: <Widget>[
            new Header(),     //頭部
            new BigDivider(),
            new TodayKb(),    //今日課表
            new BigDivider(),
            new Message(),    //消息
            new BigDivider(),
            new One()         //日知錄
          ],
        ),
      ),
    );
  }
}

//首頁的頭部信息
class Header extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 100.0,
      margin: new EdgeInsets.all(8.0),
      child: new Row(
        children: <Widget>[
          new Expanded(
            child: new Column(
              children: <Widget>[
                //頭像
                new Container(
                  width: 60.0,
                  height: 60.0,
                  margin: new EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: new AssetImage('assets/imgs/ic_menu_score.png'),
                      //從Assets加載圖片
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                new Text(
                  '查成績',
                  textAlign: TextAlign.center,
                )
              ],
            ),
            flex: 1,
          ),
          new Expanded(
            child: new Column(
              children: <Widget>[
                //頭像
                new Container(
                  width: 60.0,
                  height: 60.0,
                  margin: new EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: new AssetImage('assets/imgs/ic_menu_pe.png'),
                      //從Assets加載圖片
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                new Text(
                  '查體育',
                  textAlign: TextAlign.center,
                )
              ],
            ),
            flex: 1,
          ),
          new Expanded(
            child: new Column(
              children: <Widget>[
                //頭像
                new Container(
                  width: 60.0,
                  height: 60.0,
                  margin: new EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: new AssetImage('assets/imgs/ic_menu_bus.png'),
                      //從Assets加載圖片
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                new Text(
                  '查校車',
                  textAlign: TextAlign.center,
                )
              ],
            ),
            flex: 1,
          ),
          new Expanded(
            child: new Column(
              children: <Widget>[
                //頭像
                new Container(
                  width: 60.0,
                  height: 60.0,
                  margin: new EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: new AssetImage('assets/imgs/ic_menu_system.png'),
                      //從Assets加載圖片
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                new Text(
                  '校園系統',
                  textAlign: TextAlign.center,
                )
              ],
            ),
            flex: 1,
          ),
          new Expanded(
            child: new Column(
              children: <Widget>[
                //頭像
                new Container(
                  width: 60.0,
                  height: 60.0,
                  margin: new EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: new AssetImage('assets/imgs/ic_menu_more.png'),
                      //從Assets加載圖片
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                new Text(
                  '更多',
                  textAlign: TextAlign.center,
                )
              ],
            ),
            flex: 1,
          ),
        ],
      ),
    );
  }
}

//今日課表
class TodayKb extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Padding(
      padding: new EdgeInsets.all(18.0),
      child: new Column(
        children: <Widget>[
          new Container(
            child: new Row(
              children: <Widget>[
                new Icon(
                  Icons.camera,
                  color: Colors.black26,
                  size: 17.0,
                ),
                new Container(
                  margin: new EdgeInsets.only(left: 5.0),
                  child: new Text(
                    '今日課表',
                    style: new TextStyle(color: Color(0xFF888888)),
                  ),
                )
              ],
            ),
          ),
          new Divider(
            color: Color(0xFF888888),
          ),
          new Container(
            margin: new EdgeInsets.only(top: 30.0, bottom: 2.0),
            child: new Text("今天竟然沒有課~" + "\uD83D\uDE01"),
          ),
          new Container(
            margin: new EdgeInsets.only(top: 30.0, bottom: 2.0),
            child: new Text('點我查看完整課表',
                style: new TextStyle(
                    color: Color(
                      0xFF888888,
                    ),
                    fontSize: 12.0)),
          ),
        ],
      ),
    );
  }
}

//消息
class Message extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Padding(
      padding: new EdgeInsets.all(18.0),
      child: new Column(
        children: <Widget>[
          new Container(
            child: new Row(
              children: <Widget>[
                new Icon(
                  Icons.message,
                  color: Colors.black26,
                  size: 17.0,
                ),
                new Container(
                  margin: new EdgeInsets.only(left: 5.0),
                  child: new Text(
                    '消息',
                    style: new TextStyle(color: Color(0xFF888888)),
                  ),
                )
              ],
            ),
          ),
          new Divider(
            color: Color(0xFF888888),
          ),
          new Container(
            margin: new EdgeInsets.all(10.0),
            child: new Text("這裏是消息"),
          ),
          new Divider(
            color: Color(0xFF888888),
          )
        ],
      ),
    );
  }
}

//日知錄
class One extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Padding(
      padding: new EdgeInsets.all(18.0),
      child: new Column(
        children: <Widget>[
          new Container(
            child: new Row(
              children: <Widget>[
                new Icon(
                  Icons.email,
                  color: Colors.black26,
                  size: 17.0,
                ),
                new Container(
                  margin: new EdgeInsets.only(left: 5.0),
                  child: new Text(
                    '日知錄',
                    style: new TextStyle(color: Color(0xFF888888)),
                  ),
                )
              ],
            ),
          ),
          new Divider(
            color: Color(0xFF888888),
          ),
          new Container(
            margin: new EdgeInsets.all(10.0),
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(
                  '2018/09/14',
                  style: new TextStyle(color: Color(0xFF888888)),
                ),
                new Margin(indent: 6.0),
                new Image(
                    image: new NetworkImage(
                        'http://image.wufazhuce.com/Fn5E1UnrcvN0jwFRiOtDZ2WnQa4N')),
                new Margin(indent: 6.0),
                new Text(
                  'Fahmi Ramadhan | 攝影',
                  style: new TextStyle(color: Color(0xFF888888)),
                ),
                new Margin(indent: 6.0),
                new Text(
                  '全部的愛情,都是兩個心靈相通的人勝利,沒法相互瞭解的人失敗,沒有所謂對錯。',
                  textAlign: TextAlign.center,
                  style: new TextStyle(color: Color(0xFF888888)),
                ),
                new Margin(indent: 6.0),
                new Text(
                  '《東京愛情故事》',
                  style: new TextStyle(color: Color(0xFF888888)),
                )
              ],
            ),
          ),
          new Divider(
            color: Color(0xFF888888),
          )
        ],
      ),
    );
  }
}
複製代碼

customview.dart

import 'package:flutter/material.dart';

//分隔欄
class BigDivider extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new SizedBox(
      height: 5.0,
      child: new Center(
        child: new Container(
          height: 5.0,
          color: Colors.black12,
        ),
      ),
    );
  }
}

//間隙
class Margin extends StatelessWidget {
  final double indent;

  const Margin({Key key, this.indent: 0.0}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: new EdgeInsets.all(indent),
    );
  }
}
複製代碼
相關文章
相關標籤/搜索