利用Flutter写一个跨平台的果核APP(2)——界面篇2
2018-09-14 本文已影响36人
雇个城管打天下
前言
紧接上篇文章《利用Flutter写一个跨平台的果核APP(1)——界面篇1》
上篇文章只是将界面的基本框架搭了出来,这篇文章着手实现首页的界面。先来看预览图:
![](https://img.haomeiwen.com/i5666077/d3501e81aa64e485.png)
这是这次实现的结果图:
![](https://img.haomeiwen.com/i5666077/db3fccf00ca9ac03.png)
解析
按照图像的分割线,我将整个首页分割成头部、今日课表部分、消息部分和日知录部分
- 首先是首页的最外层框架部分
@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里面了,所以需要在开头引入
import 'package:flutter_guohe/views/customview.dart';
customview.dart中的BigDivider类
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个点需要提一下:
- 图片资源的引用
- 均分布局的实现
- 利用EventBus实现子控件控制父控件
对于第一个,其实官方文档里有介绍《资源与图像》,但是文档里写的并没有说明assets文件夹存放的路径,在这里说明一下,assets
文件夹是和lib
文件夹同级的,即
![](https://img.haomeiwen.com/i5666077/90dd8d74eef98dcc.png)
如果想要引用assets文件夹中的路径,需要先在
pubspec.yaml
文件中添加资源文件的依赖,如下所示:![](https://img.haomeiwen.com/i5666077/8cd3f0bd4cfdf2d7.png)
使用的话只需要执行
new AssetImage('assets/imgs/ic_menu_score.png'),
代码即可引用该资源文件。
第二个
![](https://img.haomeiwen.com/i5666077/55532ee6d4e105d9.png)
这里很明显是一个Row里面包含5个Column布局,而且这5个Column是均分整个Row的,怎么实现均分了,用一个Expanded()包住一个Column,然后设置其flex为1即可,这个属性就类似安卓里面的
layout_weight
,这样的话理解起来就不难了
第三个的使用场景是这样的:
![](https://img.haomeiwen.com/i5666077/1f730bac0811a2c8.png)
AppBar左上角有一个IconButton,点击该IconButton弹出Drawer,但是由于该AppBar和Drawer并不是处在同一个页面中(AppBar在today.dart文件,Drawer在app.dart文件里),所以如何跨域调用这个openDrawer()这个方法便成为了一个难题,这里推荐使用EventBus方式,具体如何操作推荐阅读《flutter基础-组件通信(父子、兄弟)》,在这种情况下Drawer和IconButton属于兄弟组件。
完整代码
today.dart
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),
);
}
}