本课时,我将在导航栏基础上,设计一个 APP 首页推荐列表,以此来讲解 Flutter 中内容多样式的展示方式。
列表的多样式包含内容+缩略图、图片九宫格以及单图信息流。接下来我将逐一讲解这三种类型的设计和实现原理。
前期准备
本课时中的列表多样式会涉及 Flutter 控件 ListView ,该控件包含了多个构造函数,比如:默认构造函数、builder、separated 和 custom。
ListView
ListView 下四种构造函数的使用场景都不相同,比如:
-
ListView 默认构造函数,适用于有限的小列表内容展示,一次性创建所有项目;
-
ListView.builder 构造函数用于处理包含大量数据的列表,其次它会在列表项滚动到屏幕上时创建该列表项;
-
ListView.separated 相比 ListView.builder 多了一个分隔符,其次更适用于固定项列表;
-
ListView.custom 可以自定义列表结构,使用场景不多,但是 ListView.builder 与 ListView.separated 都是基于 ListView.custom 来实现的。
本课时因为是一个固定有限的列表,更适用于 ListView.separated ,因此本课时基于 ListView.separated 来讲解,这里我介绍下该控件的参数列表。
ListView.separated({
Key key,
Axis scrollDirection = Axis.vertical, // 滑动方向,垂直
bool reverse = false, // 是否倒序
ScrollController controller, // 控制滚动和监听滚动事件变化
bool primary, // false内容不足不滚动,true一直可滚动
ScrollPhysics physics, // 列表滚动方式设置
bool shrinkWrap = false, // item高度适配
EdgeInsetsGeometry padding, // padding设置
@required IndexedWidgetBuilder itemBuilder, // 设置列表内容
@required IndexedWidgetBuilder separatorBuilder, // 设置分割内容
@required int itemCount, // 总数量
bool addAutomaticKeepAlives = true, // 该属性表示是否将列表项(子组件)包裹在AutomaticKeepAlive 组件中,主要是为了避免被垃圾回收
bool addRepaintBoundaries = true, // 该属性表示是否将列表项(子组件)包裹在addRepaintBoundaries 组件中,为了避免重绘
bool addSemanticIndexes = true, // 该属性表示是否将列表项(子组件)包裹在addSemanticIndexes 组件中,用来提供无障碍语义
double cacheExtent, // 设置预加载区域
})
根据以上的配置信息,我们设置了一个比较通用的配置,如下。
ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: contentList.length,
itemBuilder: (BuildContext context, int position) {
return (Widget);
},
separatorBuilder: (context, index) {
return Divider(
height: .5,
//indent: 75,
color: Color(0xFFDDDDDD),
);
},
)
上面代码配置中,scrollDirection 设置为垂直滚动,shrinkWrap 设置为高度适配,separatorBuilder 使用灰色线条分割每列数据。
以上就是 ListView 控件的一些基本知识,介绍完基本的知识点后,我们还需要做一些编码方面的前期准备。由于该交友 APP,在列表展示的是推荐帖子,因此需要使用到相应的帖子内容相关的数据结构。根据交友 APP 的数据需要,我们设计交友帖子对应的数据结构模块 Struct 、相应获取推荐帖子内容的 API 接口以及需要状态共享的 Model。
Struct
首页推荐的交友帖子数据,涉及三个具体内容:用户信息部分、交友帖子数据、帖子的评论信息。因此需要创建好三个对应的 Struct 文件。
1.user_info.dart,对应为 StructUserInfo 类,其数据结果如下。
/// 用户信息
///
/// {
/// "nickname" : "string",
/// "headerUrl" : "string",
/// "uid" : "string"
/// }
class StructUserInfo {
/// 标题
final String nickName;
/// 简要
final String headerUrl;
/// 主要内容
final String uid;
/// 默认构造函数
const StructUserInfo(
this.uid,
this.nickName,
this.headerUrl
);
}
2.content_detail.dart,对应为 StructContentDetail 类,其数据结构比较长,我们这里只是给个 JSON 的例子,代码如下。
{
"id" : "string",
"title" : "string",
"summary" : "string",
"detailInfo" : "string",
"uid" : "string",
"userInfo" : "StructUserInfo",
"articleImage" : "string",
"likeNum" : "int",
"commentNum" : "int"
}
3.comment_info.dart,对应为 StructCommentInfo 类,代码如下。
import 'package:two_you_friend/util/struct/user_info.dart';
/// 用户信息
///
/// {
/// "userInfo" : "StructUserInfo",
/// "comment" : &