Flutter学习-13- 微信项目学习-发现页面
- 前言:我们实现微信的发现页面
首先观察下这是个
ListView
,分为几个组,每个row
类似,但是其中购物右边有的cell
具有状态,活动说明
和小红点
,以及cell分割线
。基本上就是一个经典的iOS的tableview
,其中cell为静态页面cell
。
1. 自定义cell
我们首先分析cell
,cell可以说有6
个元素,图标,标题,活动描述,红点,cell的箭头,分割线也可以算一个。分析其中标题和图标是必填的我们可以自定义构造函数为必填,这里每个cell都有箭头
>可以不用定义,cell分割线我们也可以到时候根据index
进行判断。
class DiscoverCell extends StatelessWidget {
String? iconImageName;
String? title;
String? desTitle;
String? desIconImageName;
DiscoverCell({
required this.title,
required this.iconImageName,
this.desIconImageName,
this.desTitle
}):assert(title != null,'标题不可为空'),
assert(iconImageName != null,'图标不能为空');
@override
Widget build(BuildContext context) {
return Container(
);
}
}
对于cell我们使用时间row布局
中的均分布局spaceBetween
其效果就是组件2边向中间布局,中间的空隙相等,符合我们的需求。
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,//cell分为2份
children: [
//左边
Container(
child: Row(children: [
Image.asset(iconImageName!,width: 20,),
Text(title!),
],),
),
//右边
Container(
child: Row(
children: [
desTitle != null ? Text(desTitle!) :Container(),
desIconImageName != null ? Image.asset(desIconImageName!) :Container(),
Image.asset('images/icon_right.png',)//箭头
],
),
)
],
),
我们先定义下cell
,右边Container
中我们根据标题和红点图片是否展示之后我们把需要的2种状态进行展示放入listview
中
child: ListView(
children: [
DiscoverCell(title: '朋友圈', iconImageName: 'images/朋友圈.png'),
DiscoverCell(title: '购物',iconImageName: 'images/购物.png',desTitle: '618限时特价',desIconImageName:'images/badge.png' ,)
],
),
我们图片和间距都没设置,但是元素都展示了
Widget build(BuildContext context) {
return Container(
height: 44,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,//cell分为2份
children: [
//左边
Container(
padding: EdgeInsets.all(10),
child: Row(children: [
Image.asset(iconImageName!,width: 20,),
SizedBox(width: 10,),
Text(title!),
],),
),
//右边
Container(
child: Row(
children: [
desTitle != null ? Text(desTitle!) :Container(),
desIconImageName != null ? Image.asset(desIconImageName!,width: 20,) :Container(),
Image.asset('images/icon_right.png',width: 15,),//箭头
SizedBox(width: 15,)
],
),
)
],
),
);
设置行高和间距
,以及图片大小
。
2. cell的分割线
我们有2种思路,一种是把分割线也当成一个row组件
放在listView的children
中
children: [
DiscoverCell(title: '朋友圈', iconImageName: 'images/朋友圈.png'),
Row(children: <Widget>[Container(width: 50, height: 1, color: Colors.white),
Container(height: 1, color: Colors.grey)
],
),
DiscoverCell(title: '购物',iconImageName: 'images/购物.png',desTitle: '618限时特价',desIconImageName:'images/badge.png' ,)
],
相当于把cell分割线
分为2
种颜色,这样可以就可以区分出来了。
我们也可以使用stack进行叠放
,以底部左边对齐方式,我们把线放在底部设置背景色,设置下左间距。
当然我们也可以使用其它的一些方式设置分割线,比如Divider
Divider(height: 0.5,color: Colors.grey,indent: 50,),
indent
为起始缩进,endIndent
为末尾缩进
前面起始缩进为背景颜色导致的,比如我设置首末尾都是50,颜色为红色
- DecoratedBox
DecoratedBox(decoration: BoxDecoration(
border: Border.all(color: Colors.grey,width: 0.5)
)),
新建一个不带child Widget
的装饰容盒子,只使用边框参数,相当于一个没有高度的空白盒子
。
3. 页面跳转以及点击效果
其它cell类似,我们把标题和图片加上去
我们看下cell的点击实现
通过GestureDetector
这个手势的widget进行实现
这里面有很多状态实现的回调
这里我们使用ontap
来实现
需要传递一个路由
我们定义一个子页面
class DiscoverChildPage extends StatelessWidget {
final String? title;
DiscoverChildPage(this.title);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title??""),
),
body: Container(),
);
}
}
实现跳转
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => DiscoverChildPage(title)));
怎么实现点击的时候类似我们iOS中选中
的效果呢?
因为要改变cell的选中背景,因此改为StatefulWidget
我们就要使用widget来使用属性
Color _currentColor = Colors.white;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => DiscoverChildPage(widget.title)));
setState(() {
_currentColor = Colors.white;
});
},
onTapDown: (TapDownDetails details) {
setState(() {
_currentColor = Colors.grey;
});
},
onTapCancel: () {
setState(() {
_currentColor = Colors.white;
});
},
}