- (7)CollectionPage
--组件收藏页面
CollectionPage
页面相对比较简单,就一个列表页面,开始吧。
初始化方法:
_CollectionPageState() {
final eventBus = new EventBus();
ApplicationEvent.event = eventBus;
}
CollectionControlModel _collectionControl = new CollectionControlModel();
List<Collection> _collectionList = [];
ScrollController _scrollController = new ScrollController();
var _icons;
@override
void initState() {
super.initState();
_getList();
ApplicationEvent.event.on<CollectionEvent>().listen((event) {//订阅
_getList();
});
}
-
ApplicationEvent
ApplicationEvent
是通过event_bus
三方进行组件间事件传递的工具。event_bus
这个库大家有兴趣可以自行去了解。
订阅:
ApplicationEvent.event.on<CollectionEvent>().listen((event) {//订阅
_getList();
});
发送通知:
ApplicationEvent.event
.fire(CollectionEvent(widget.title, _router, true));
-
CollectionControlModel
CollectionControlModel
负责收藏数据的存取,和上面的CatControlModel
差不多:
final String table = 'collection';
Sql sql;
CollectionControlModel() {//set 表名
sql = Sql.setTable(table);
}
// 获取所有的收藏
// 插入新收藏
Future insert(Collection collection) {
var result =
sql.insert({'name': collection.name, 'router': collection.router});
return result;
}
// 获取全部的收藏
Future<List<Collection>> getAllCollection() async {
List list = await sql.getByCondition();
List<Collection> resultList = [];
list.forEach((item){
print(item);
resultList.add(Collection.fromJSON(item));
});
return resultList;
}
// 通过收藏名获取router
Future getRouterByName(String name) async {
List list = await sql.getByCondition(conditions: {'name': name});
return list;
}
// 删除
Future deleteByName(String name) async{
return await sql.delete(name,'name');
}
-
build
函数
build
的主要内容在_renderList
方法里面:
Widget _renderList(context, index) {
if (index == 0) {
return Container(//头部标题
height: 40.0,
padding: const EdgeInsets.only(left: 10.0),
child: Row(
children: <Widget>[
Icon(
Icons.warning,
size: 22.0,
),
SizedBox(
width: 5.0,
),
Text('模拟器重新运行会丢失收藏'),
],
),
);
}
if (_collectionList[index - 1].router.contains('http')) {
if (_collectionList[index - 1].name.endsWith('Doc')) {
_icons = Icons.library_books;
} else {
_icons = Icons.language;
}
} else {
_icons = Icons.extension;
}
return Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
margin: const EdgeInsets.only(bottom: 7.0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
new BoxShadow(
color: const Color(0xFFd0d0d0),
blurRadius: 1.0,
spreadRadius: 2.0,
offset: Offset(3.0, 2.0),
),
],
),
child: ListTile(
leading: Icon(
_icons,
size: 30.0,
color: Theme.of(context).primaryColor,
),
title: Text(
Uri.decodeComponent(_collectionList[index - 1].name),
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 17.0),
),
trailing:
Icon(Icons.keyboard_arrow_right, color: Colors.grey, size: 30.0),
onTap: () {
if (_collectionList[index - 1].router.contains('http')) {//如果是网页就直接跳转
// 注意这里title已经转义过了
Application.router.navigateTo(context,
'${Routes.webViewPage}?title=${_collectionList[index - 1].name}&url=${Uri.encodeComponent(_collectionList[index - 1].router)}');
} else {//不是网页就跳转相应的页面
Application.router
.navigateTo(context, "${_collectionList[index - 1].router}");
}
},
),
);
}
- (8)FourthPage
--第四个页面
这个页面看似比较复杂,但是实际层级结构还是很清晰的:
Widget build(BuildContext context) {
return new Stack(
children: [
new Page(
// page 的主要内容
viewModel: pages[activeIndex],
percentVisible: 1.0,
),
new PageReveal(//动画page
revealPercent: slidePercent,
child: new Page(
viewModel: pages[nextPageIndex],
percentVisible: slidePercent,
),
),
new PagerIndicator(//指示
viewModel: new PagerIndicatorViewModel(
pages,
activeIndex,
slideDirection,
slidePercent,
),
),
new PageDragger(//负责滑动-->手势
canDragLeftToRight: activeIndex > 0,
canDragRightToLeft: activeIndex < pages.length - 1,
slideUpdateStream: this.slideUpdateStream,
)
],
);
}
代码我已经尽量添加了详细的注释,可以看到分成四个部分:Page
(主要内容的显示页面activePage)、PageReveal
(用于操作nextPage执行滑动动画)、PagerIndicator
(滑动指示条)、PageDragger
(滑动手势)
-
Page
(主要内容的显示页面)
初始化相关:
final PageViewModel viewModel;
final double percentVisible;
Page({
this.viewModel,//页面信息
this.percentVisible = 1.0,//滑动百分百
});
build
函数
Widget build(BuildContext context) {
return Stack(
//alignment: const Alignment(1.2, 0.6),
children: [
Container(
width: double.infinity,
/// height:MediaQuery.of(context).size.height-200.0,
color: viewModel.color,
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Opacity(
opacity: percentVisible,
child: ListView(
children: <Widget>[
layout(context),
],
),
)
),
Positioned(//右上角GitHub 按钮
right: -5.0,
top: 2.0,
child: creatButton(context, 'GitHub', Icons.arrow_forward, 'goGithub')
),
]
);
}
在build
函数中我们可以看到结构分为两部分,layout(主要视图)、creatButton(左上角github按钮)。
layout
Column layout(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Transform(//这个动画效果是 向上慢慢移动的效果
transform: Matrix4.translationValues(
0.0, 50.0 * (1.0 - percentVisible), 0.0),
child: Padding(
padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
child: Image.asset(viewModel.heroAssetPath,
width: 160.0, height: 160.0),
),
),
Transform(//这个动画效果是 向上慢慢移动的效果
transform: Matrix4.translationValues(
0.0, 30.0 * (1.0 - percentVisible), 0.0),
child: Padding(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
child: Text(
viewModel.title,
style: TextStyle(
color: Colors.white,
fontFamily: 'FlamanteRoma',
fontSize: 28.0,
),
),
),
),
Transform(//这个动画效果是 向上慢慢移动的效果
transform: Matrix4.translationValues(
0.0, 30.0 * (1.0 - percentVisible), 0.0),
child: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: Text(
viewModel.body,
textAlign: TextAlign.center,
style: TextStyle(
height: 1.2,
color: Colors.white,
fontFamily: 'FlamanteRomaItalic',
fontSize: 18.0,
),
),
),
),
// ButtonBar(
// alignment: MainAxisAlignment.center,
// children: <Widget>[
// creatButton(context, '开始使用', Icons.add_circle_outline, 'start'),
// creatButton(context, 'GitHub', Icons.arrow_forward, 'goGithub'),
// ],
// )
]);
}
creatButton
Widget creatButton(
BuildContext context, String txt, IconData iconName, String type) {
return RaisedButton.icon(
onPressed: () async {
if (type == 'start') {//这是看代码应该是关闭 欢迎页
await SpUtil.getInstance()
..putBool(SharedPreferencesKeys.showWelcome, false);
_goHomePage(context);
} else if (type == 'goGithub') {//跳转 github
Application.router.navigateTo(context,
'${Routes.webViewPage}?title=${Uri.encodeComponent(txt)} Doc&&url=${Uri.encodeComponent("https://github.com/alibaba/flutter-go")}');
}
},
elevation: 10.0,
color: Colors.black26,
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.horizontal(left: Radius.circular(20.0))),
//如果不手动设置icon和text颜色,则默认使用foregroundColor颜色
icon: Icon(iconName, color: Colors.white, size: 14.0),
label: Text(
txt,
maxLines: 1,
style: TextStyle(
color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700),
));
}
这里我都在原来的基础上加上了一些注释,可以结合看,我不多说了。