254 lines
8.2 KiB
Dart
254 lines
8.2 KiB
Dart
import 'dart:math';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:aesthetica_wallpaper/providers/editor_provider.dart';
|
|
|
|
/// 推荐列表页面 - 从每个类别随机选择3张图片
|
|
class RecommendationListScreen extends StatefulWidget {
|
|
const RecommendationListScreen({super.key});
|
|
|
|
@override
|
|
State<RecommendationListScreen> createState() =>
|
|
_RecommendationListScreenState();
|
|
}
|
|
|
|
class _RecommendationListScreenState extends State<RecommendationListScreen> {
|
|
final Random _random = Random();
|
|
List<String> _recommendedImages = [];
|
|
|
|
// 所有可用的图片列表(按类别组织)
|
|
static const Map<String, List<String>> _allImages = {
|
|
'nature': [
|
|
'assets/images/nature/nature1.png',
|
|
'assets/images/nature/nature2.png',
|
|
'assets/images/nature/nature3.png',
|
|
'assets/images/nature/nature4.png',
|
|
'assets/images/nature/nature5.png',
|
|
'assets/images/nature/nature6.png',
|
|
'assets/images/nature/nature7.png',
|
|
'assets/images/nature/nature8.png',
|
|
'assets/images/nature/nature9.png',
|
|
],
|
|
'abstract': [
|
|
'assets/images/abstract/abstract1.png',
|
|
'assets/images/abstract/abstract2.png',
|
|
'assets/images/abstract/abstract3.png',
|
|
'assets/images/abstract/abstract4.png',
|
|
'assets/images/abstract/abstract5.png',
|
|
'assets/images/abstract/abstract6.png',
|
|
'assets/images/abstract/abstract7.png',
|
|
'assets/images/abstract/abstract8.png',
|
|
'assets/images/abstract/abstract9.png',
|
|
'assets/images/abstract/abstract10.png',
|
|
'assets/images/abstract/abstract11.png',
|
|
'assets/images/abstract/abstract12.png',
|
|
'assets/images/abstract/abstract13.png',
|
|
'assets/images/abstract/abstract14.png',
|
|
'assets/images/abstract/abstract15.png',
|
|
],
|
|
'architecture': [
|
|
'assets/images/architecture/architecture1.png',
|
|
'assets/images/architecture/architecture2.png',
|
|
'assets/images/architecture/architecture3.png',
|
|
'assets/images/architecture/architecture4.png',
|
|
'assets/images/architecture/architecture5.png',
|
|
'assets/images/architecture/architecture6.png',
|
|
'assets/images/architecture/architecture7.png',
|
|
'assets/images/architecture/architecture8.png',
|
|
'assets/images/architecture/architecture9.png',
|
|
'assets/images/architecture/architecture10.png',
|
|
],
|
|
'animals': [
|
|
'assets/images/animals/animals1.png',
|
|
'assets/images/animals/animals2.png',
|
|
'assets/images/animals/animals3.png',
|
|
'assets/images/animals/animals4.png',
|
|
'assets/images/animals/animals5.png',
|
|
'assets/images/animals/animals6.png',
|
|
'assets/images/animals/animals7.png',
|
|
],
|
|
'food': [
|
|
'assets/images/food/food1.png',
|
|
'assets/images/food/food2.png',
|
|
'assets/images/food/food3.png',
|
|
'assets/images/food/food4.png',
|
|
'assets/images/food/food5.png',
|
|
'assets/images/food/food6.png',
|
|
'assets/images/food/food7.png',
|
|
'assets/images/food/food8.png',
|
|
'assets/images/food/food9.png',
|
|
'assets/images/food/food10.png',
|
|
'assets/images/food/food11.png',
|
|
'assets/images/food/food12.png',
|
|
'assets/images/food/food13.png',
|
|
],
|
|
'travel': [
|
|
'assets/images/travel/travel1.png',
|
|
'assets/images/travel/travel2.png',
|
|
'assets/images/travel/travel3.png',
|
|
'assets/images/travel/travel4.png',
|
|
'assets/images/travel/travel5.png',
|
|
'assets/images/travel/travel6.png',
|
|
'assets/images/travel/travel7.png',
|
|
'assets/images/travel/travel8.png',
|
|
'assets/images/travel/travel9.png',
|
|
],
|
|
};
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadRecommendedImages();
|
|
}
|
|
|
|
void _loadRecommendedImages() {
|
|
final images = <String>[];
|
|
|
|
// 从每个类别随机选择3张图片
|
|
_allImages.forEach((category, categoryImages) {
|
|
final shuffled = List<String>.from(categoryImages)..shuffle(_random);
|
|
images.addAll(shuffled.take(3));
|
|
});
|
|
|
|
// 打乱最终列表
|
|
images.shuffle(_random);
|
|
|
|
setState(() {
|
|
_recommendedImages = images;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: CustomScrollView(
|
|
slivers: [
|
|
// AppBar
|
|
SliverAppBar(
|
|
expandedHeight: 120,
|
|
floating: false,
|
|
pinned: true,
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
title: const Text(
|
|
'Daily Picks',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
background: Container(
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
colors: [Colors.orange.shade400, Colors.pink.shade400],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
actions: [
|
|
IconButton(
|
|
icon: const Icon(Icons.refresh),
|
|
tooltip: 'Refresh',
|
|
onPressed: _loadRecommendedImages,
|
|
),
|
|
],
|
|
),
|
|
|
|
// 推荐说明
|
|
SliverToBoxAdapter(
|
|
child: Container(
|
|
margin: const EdgeInsets.all(16),
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: BoxDecoration(
|
|
color: Colors.orange.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(color: Colors.orange.withValues(alpha: 0.3)),
|
|
),
|
|
child: const Row(
|
|
children: [
|
|
Icon(Icons.info_outline, color: Colors.orange),
|
|
SizedBox(width: 12),
|
|
Expanded(
|
|
child: Text(
|
|
'Curated wallpapers from all categories, tap to view details',
|
|
style: TextStyle(fontSize: 14),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
// 图片网格
|
|
SliverPadding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
sliver: SliverGrid(
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 2,
|
|
mainAxisSpacing: 12,
|
|
crossAxisSpacing: 12,
|
|
childAspectRatio: 0.7,
|
|
),
|
|
delegate: SliverChildBuilderDelegate((context, index) {
|
|
return _buildImageItem(_recommendedImages[index]);
|
|
}, childCount: _recommendedImages.length),
|
|
),
|
|
),
|
|
|
|
// 底部间距
|
|
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildImageItem(String imagePath) {
|
|
return GestureDetector(
|
|
onTap: () {
|
|
// 初始化编辑器并跳转
|
|
Provider.of<EditorProvider>(
|
|
context,
|
|
listen: false,
|
|
).startEditing(imagePath);
|
|
Navigator.pushNamed(context, '/editor');
|
|
},
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withValues(alpha: 0.1),
|
|
blurRadius: 8,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(16),
|
|
child: Stack(
|
|
fit: StackFit.expand,
|
|
children: [
|
|
Image.asset(imagePath, fit: BoxFit.cover),
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
begin: Alignment.topCenter,
|
|
end: Alignment.bottomCenter,
|
|
colors: [
|
|
Colors.transparent,
|
|
Colors.black.withValues(alpha: 0.3),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const Positioned(
|
|
bottom: 8,
|
|
right: 8,
|
|
child: Icon(Icons.edit, color: Colors.white, size: 24),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|