前言
通过观察整理微信的发现页,整理功能点如下:
- 1.发现页分组列表
完成 ✅ - 2.朋友圈未读小红点和头像
未完成 ❌
预览
思路
- 与通讯录列表一样,采用分组的思想,同组之间没有间隔,不同组之间使用间隔分割。
实现
定义数据结构
class DiscoverGroupData {
const DiscoverGroupData({required this.groupName, required this.list});
/// 名称
final String groupName;
/// 数据
final List<DiscoverData> list;
}
class DiscoverData {
const DiscoverData(
{required this.name, required this.icon, required this.isNewMsg});
/// 名称
final String name;
/// 图标
final String icon;
/// 是否有新消息
final bool isNewMsg;
}
封装组件
class GroupView extends StatelessWidget {
const GroupView({Key? key, this.child}) : super(key: key);
final Widget? child;
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Style.contentBackgroundColor,
child: child,
),
const SizedBox(height: 20),
],
);
}
}
class GroupItemView extends StatelessWidget {
const GroupItemView(
this.list, {
Key? key,
this.child,
}) : super(key: key);
final List<DiscoverData> list;
final Widget? child;
@override
Widget build(BuildContext context) {
return Column(
children: list
.asMap()
.entries
.map((item) => Column(
children: [
ListTile(
leading: Image.asset(item.value.icon,width: 54,height: 54,),
title: Text(item.value.name),
trailing: const Icon(Icons.chevron_right),
),
if (item.key != list.length - 1)
const Padding(
padding: EdgeInsets.only(left: 70),
child: Divider(height: 2),
)
],
))
.toList(),
);
}
}
完整代码
import 'package:flutter/material.dart';
import 'package:pseudo_we_chat/constant/style.dart';
import 'package:pseudo_we_chat/ui/font/WeChatFont.dart';
class DiscoverPage extends StatefulWidget {
const DiscoverPage({Key? key}) : super(key: key);
@override
State<DiscoverPage> createState() => _DiscoverPageState();
}
class _DiscoverPageState extends State<DiscoverPage> {
final List<DiscoverGroupData> _list = const [
DiscoverGroupData(groupName: "a", list: [
DiscoverData(
name: "朋友圈", icon: "images/friend_circle.png", isNewMsg: false)
]),
DiscoverGroupData(groupName: "b", list: [
DiscoverData(name: "视频号", icon: "images/video.png", isNewMsg: true),
DiscoverData(name: "直播", icon: "images/direct_seeding.png", isNewMsg: true),
]),
DiscoverGroupData(groupName: "c", list: [
DiscoverData(name: "扫一扫", icon: "images/sweep.png", isNewMsg: false),
]),
DiscoverGroupData(groupName: "d", list: [
DiscoverData(name: "搜一搜", icon: "images/search.png", isNewMsg: false),
]),
DiscoverGroupData(groupName: "e", list: [
DiscoverData(name: "附近", icon: "images/address.png", isNewMsg: false),
]),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
title: const Text(
"发现",
style: TextStyle(color: Style.appBarTextColor),
),
backgroundColor: Style.appBarBackgroundColor),
body: Container(
color: Style.scaffoldBackgroundColor,
child: ListView.builder(
itemCount: _list.length,
itemBuilder: (context, index) {
return GroupView(
child: GroupItemView(_list[index].list),
);
}),
));
}
}
class GroupView extends StatelessWidget {
const GroupView({Key? key, this.child}) : super(key: key);
final Widget? child;
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Style.contentBackgroundColor,
child: child,
),
const SizedBox(height: 20),
],
);
}
}
class GroupItemView extends StatelessWidget {
const GroupItemView(
this.list, {
Key? key,
this.child,
}) : super(key: key);
final List<DiscoverData> list;
final Widget? child;
@override
Widget build(BuildContext context) {
return Column(
children: list
.asMap()
.entries
.map((item) => Column(
children: [
ListTile(
leading: Image.asset(item.value.icon,width: 54,height: 54,),
title: Text(item.value.name),
trailing: const Icon(Icons.chevron_right),
),
if (item.key != list.length - 1)
const Padding(
padding: EdgeInsets.only(left: 70),
child: Divider(height: 2),
)
],
))
.toList(),
);
}
}
class DiscoverGroupData {
const DiscoverGroupData({required this.groupName, required this.list});
/// 名称
final String groupName;
/// 数据
final List<DiscoverData> list;
}
class DiscoverData {
const DiscoverData(
{required this.name, required this.icon, required this.isNewMsg});
/// 名称
final String name;
/// 图标
final String icon;
/// 是否有新消息
final bool isNewMsg;
}