沸点 UI & 功能 编写(下)
Nealyang opened this issue · 0 comments
Nealyang commented
前言
上一章节中,我们完成了沸点页面部分UI的编写,这一章节,我们将完成沸点页面剩余页面的代码编写
cell组件编写
通过拿到的cell数据去判断为哪一类cell
widget.pinsCell.url == ''
? PinsCellPic(
pics: widget.pinsCell.pictures,
)
: PinsCellUrl(
url: widget.pinsCell.url,
urlPic: widget.pinsCell.urlPic,
urlTitle: widget.pinsCell.urlTitle,
),
- 当cell中的数据包含url这个的时候,说明是link类型的cell
- lib/widget/pins_cell_url.dart
@override
Widget build(BuildContext context) {
return InkWell(
onTap: (){
Application.router.navigateTo(context,"/web?url=${Uri.encodeComponent(url)}&title=${Uri.encodeComponent(urlTitle)}");
},
child: Container(
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.symmetric(horizontal: 14.0,vertical: 10.0),
height: 100,
decoration: BoxDecoration(
border:
Border.all(color: Theme.of(context).accentColor, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(4.0))),
child: Row(
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
urlTitle,
style:
TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
Text(
url,
style: TextStyle(
fontSize: 15.0, color: Theme.of(context).accentColor),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
flex: 2,
),
Expanded(
flex: 1,
child: Image.network(urlPic),
)
],
)),
);
}
- 最外层使用InkWell包裹,这个应该不默认,其实就是为了绑定点击事件,点击后,跳转到链接地址
- 外层通过Container 包裹,去设置一些样式,比如padding、margin、height以及border的设置
- 里面我们通过Row去横向排列子组件,里面我们使用Expanded组件,是为了能够完全的撑开Row的内容
图片查看页面
下面我们新建一个页面,用于查看图片
- lib/pages/swip_page.dart
@override
Widget build(BuildContext context) {
List picList = pics.split(',');
int index = int.parse(currentIndex);
return Center(
child: Swiper(
itemBuilder: (BuildContext context, int index) {
return new Image.network(
picList[index],
fit: BoxFit.fitWidth,
width: MediaQuery.of(context).size.width,
);
},
itemCount: picList.length,
scale: 0.8,
pagination: new SwiperPagination(),
index: index,
onTap: (index) {
Application.router.pop(context);
},
),
);
}
- 这里我们引入flutter package:flutter swiper。关于如何引入以及查找相关package,之前已经介绍过,这里就不多说了。
- 设置itemCount为我们传入的图片数目。并且设置指示器
- 点击页面的时候,退出页面
在 lib/routers
下注入相关页面后,即可来编写cell的图片部分,并完成页面的跳转以查看图片
- lib/widget/pins_cell_pic.dart
@override
Widget build(BuildContext context) {
if (pics.length > 3) {
_picHeight = 190.0;
}
for (int i = 0; i < pics.length; i += 3) {
List<Widget> _tempRow = List();
_tempRow.add(
Expanded(
child: InkWell(
onTap: () {
Application.router.navigateTo(context,
'/swip?pics=${Uri.encodeComponent(_buildPicsStr())}¤tIndex=${i.toString()}',transition: TransitionType.fadeIn);
},
child: Image.network(
pics[i],
fit: BoxFit.cover,
height: _picHeight,
),
),
flex: 1,
),
);
if (i + 1 < pics.length) {
_tempRow.add(
SizedBox(
width: 10.0,
),
);
_tempRow.add(
Expanded(
child: InkWell(
onTap: () {
Application.router.navigateTo(context,
'/swip?pics=${Uri.encodeComponent(_buildPicsStr())}¤tIndex=${i.toString()}');
},
child: Image.network(
pics[i + 1],
fit: BoxFit.cover,
height: _picHeight,
),
),
flex: 1,
),
);
}
if (i + 2 < pics.length) {
_tempRow.add(
SizedBox(
width: 10.0,
),
);
_tempRow.add(
Expanded(
child: InkWell(
onTap: () {
Application.router.navigateTo(context,
'/swip?pics=${Uri.encodeComponent(_buildPicsStr())}¤tIndex=${i.toString()}');
},
child: Image.network(
pics[i + 2],
fit: BoxFit.cover,
height: _picHeight,
),
),
flex: 1,
),
);
}
_wrapChildren.add(Container(
child: Row(
children: _tempRow,
),
margin: const EdgeInsets.only(bottom: 10.0),
));
}
return Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: Wrap(
children: _wrapChildren,
),
);
}
- 首先我们需要注意的是,这里我们不能使用GridView来实现我们的图片,除非我们能够给最外层一个限定高度的Container,但是,根据我们页面的UI,这个高度是不能固定的。且,当我们给定了Container一个固定高度,Container内容还是会有滚动标签在。所以这里我们不适用GridView布局。
- 点击跳转页面,并且传递当前点击的图片的index
- 根据图片的数目不同,设置不同的图片高度。
- 跳转页面的时候,使用了
TransitionType.fadeIn
来设置页面的跳转动画,这些大家都可以自行设置查看相应效果。注意TransitionType属于fluro的方法,所以使用时需要引入包:import 'package:fluro/fluro.dart';
完成代码查看:代码地址
效果如如下:
代码中同级目录包括沸点cell的底部 点赞和评论的widget的编写,地址为:lib/widget/pins_cell_bottom_button.dart 代码比较简单也比较常规,大家可以自行查看编写相应UI。
cell widget 组合
完成了沸点cell的每一个小部分的代码编写,下面将这些小组件拼接成我们完整的一个沸点的cell吧
- lib/widgets/pins_list_cell.dart
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
margin: const EdgeInsets.only(top: 10.0),
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.symmetric(horizontal: 9.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
PinsCellHeader(
userInfo: widget.pinsCell.user,
createdAt: widget.pinsCell.createdAt),
_renderContent(widget.pinsCell.content),
widget.pinsCell.url == ''
? PinsCellPic(
pics: widget.pinsCell.pictures,
)
: PinsCellUrl(
url: widget.pinsCell.url,
urlPic: widget.pinsCell.urlPic,
urlTitle: widget.pinsCell.urlTitle,
),
widget.pinsCell.topic.length == 0
? Container()
: PinsCellTopic(
topicInfo: widget.pinsCell.topic,
),
],
),
),
PinsCellBottomButton(
commentCount: widget.pinsCell.commentCount,
likedCount: widget.pinsCell.likedCount,
),
],
),
);
}
这部分代码就是将我们编写的所有颗粒度非常小的widget组合使用成我们需要的UI。
总结
如上,我们就完成了沸点部分的编写。需要注意的是,这部分UI非常的多而杂。但是其实难度都不是很大,将大的页面,细分为一个一个颗粒度非常细的组件使我们应该学会的。注意,一定要根据自己的理解、业务的需求去合理划分组件。不可盲目细化导致杂乱。