feat:更新页面颜色
This commit is contained in:
277
lib/pages/explore_page.dart
Normal file
277
lib/pages/explore_page.dart
Normal 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(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user