feat:更新页面颜色

This commit is contained in:
2026-06-17 13:24:37 +08:00
parent 021db2efac
commit 02084ada96
9 changed files with 601 additions and 341 deletions

277
lib/pages/explore_page.dart Normal file
View File

@@ -0,0 +1,277 @@
import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
class Comment {
final String nickname;
final String content;
Comment({required this.nickname, required this.content});
}
class Moment {
final String avatar;
final String nickname;
final String content;
final List<String> images;
bool liked;
int likeCount;
List<Comment> comments;
Moment({
required this.avatar,
required this.nickname,
required this.content,
this.images = const [],
this.liked = false,
this.likeCount = 0,
this.comments = const [],
});
}
/// ================= Explore Page =================
class ExplorePage extends StatefulWidget {
const ExplorePage({super.key});
@override
State<ExplorePage> createState() => _ExplorePageState();
}
class _ExplorePageState extends State<ExplorePage> {
final List<Moment> _moments = [
Moment(
avatar: 'https://picsum.photos/100?random=1',
nickname: '张三',
content: '今天天气真不错 ☀️',
images: [
'https://picsum.photos/300?random=1',
'https://picsum.photos/300?random=2',
'https://picsum.photos/300?random=3',
'https://picsum.photos/300?random=4',
'https://picsum.photos/300?random=5',
],
likeCount: 12,
comments: [
Comment(nickname: '李四', content: '确实不错'),
Comment(nickname: '王五', content: '想去旅游'),
],
),
Moment(
avatar: 'https://picsum.photos/100?random=2',
nickname: '李四',
content: 'Flutter 真香 🚀',
images: ['https://picsum.photos/300?random=6'],
likeCount: 8,
comments: [],
),
];
void _handleLike(int index) {
setState(() {
final m = _moments[index];
m.liked ? m.likeCount-- : m.likeCount++;
m.liked = !m.liked;
});
}
void _handleComment(int index, String text) {
setState(() {
_moments[index].comments.add(Comment(nickname: '', content: text));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
appBar: _buildAppBar(),
body: Padding(padding: const EdgeInsets.all(10), child: _buildMoment()),
);
}
PreferredSizeWidget _buildAppBar() {
return AppBar(
automaticallyImplyLeading: false,
backgroundColor: Color(0xFF120D25),
elevation: 0,
centerTitle: true,
title: const Text(
'朋友圈',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.add, size: 22, color: Colors.white),
splashRadius: 20,
),
],
);
}
Widget _buildMoment() {
return ListView.separated(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom + 80,
),
separatorBuilder: (BuildContext context, int index) {
return SizedBox(height: 10);
},
itemCount: _moments.length,
itemBuilder: (context, index) {
return MomentItem(
moment: _moments[index],
onLike: () => _handleLike(index),
onComment: (text) => _handleComment(index, text),
);
},
);
}
}
/// ================= Moment Item =================
class MomentItem extends StatefulWidget {
final Moment moment;
final VoidCallback onLike;
final Function(String) onComment;
const MomentItem({
super.key,
required this.moment,
required this.onLike,
required this.onComment,
});
@override
State<MomentItem> createState() => _MomentItemState();
}
class _MomentItemState extends State<MomentItem> {
final TextEditingController _controller = TextEditingController();
void _submit() {
if (_controller.text.trim().isEmpty) return;
widget.onComment(_controller.text.trim());
_controller.clear();
}
@override
Widget build(BuildContext context) {
final m = widget.moment;
return GlassCard(
padding: const EdgeInsets.all(12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(backgroundImage: NetworkImage(m.avatar)),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
m.nickname,
style: const TextStyle(
color: Colors.purple,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 6),
Text(m.content, style: const TextStyle(color: Colors.white)),
if (m.images.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 8),
child: LayoutBuilder(
builder: (context, constraints) {
final isSingle = m.images.length == 1;
final itemWidth =
isSingle ? 180.0 : (constraints.maxWidth - 8) / 3;
return Wrap(
spacing: 4,
runSpacing: 4,
children:
m.images.map((url) {
return ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Image.network(
url,
width: itemWidth,
height: itemWidth,
fit: BoxFit.cover,
),
);
}).toList(),
);
},
),
),
const SizedBox(height: 4),
Row(
children: [
Badge(
label: Text('${m.likeCount}'),
isLabelVisible: m.likeCount > 0,
offset: const Offset(0, 0),
child: IconButton(
onPressed: widget.onLike,
icon: Icon(
m.liked ? Icons.favorite : Icons.favorite_border,
color: m.liked ? Colors.red : Colors.grey,
),
),
),
Badge(
label: Text('${m.comments.length}'),
isLabelVisible: m.comments.length > 0,
offset: const Offset(0, 0),
child: IconButton(
onPressed: () => {},
icon: Icon(Icons.comment, color: Colors.grey),
),
),
],
),
if (m.comments.isNotEmpty)
Container(
width: double.infinity,
margin: const EdgeInsets.only(top: 6),
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Color(0xFF120D25),
borderRadius: BorderRadius.circular(6),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:
m.comments
.map(
(c) => Text(
'${c.nickname}${c.content}',
style: const TextStyle(
fontSize: 13,
color: Colors.white,
),
),
)
.toList(),
),
),
],
),
),
],
),
);
}
}