petsHero-AI/lib/features/gallery/gallery_screen.dart
2026-03-09 11:41:49 +08:00

104 lines
3.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_spacing.dart';
import '../../shared/widgets/top_nav_bar.dart';
/// Gallery screen - matches Pencil hpwBg
class GalleryScreen extends StatelessWidget {
const GalleryScreen({super.key});
static const _galleryImages = [
'https://images.unsplash.com/photo-1763929272543-0df093e4f659?w=400',
'https://images.unsplash.com/photo-1703592819695-ea63799b7315?w=400',
'https://images.unsplash.com/photo-1764787435677-1321e12559e3?w=400',
'https://images.unsplash.com/photo-1759264244741-7175af0b7e75?w=400',
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.background,
appBar: PreferredSize(
preferredSize: const Size.fromHeight(56),
child: TopNavBar(
title: 'Gallery',
credits: '1,280',
onCreditsTap: () => Navigator.of(context).pushNamed('/recharge'),
),
),
body: LayoutBuilder(
builder: (context, constraints) {
return Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 390),
child: GridView.builder(
padding: const EdgeInsets.fromLTRB(
AppSpacing.screenPadding,
AppSpacing.xl,
AppSpacing.screenPadding,
AppSpacing.screenPaddingLarge,
),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 165 / 248,
mainAxisSpacing: AppSpacing.xl,
crossAxisSpacing: AppSpacing.xl,
),
itemCount: _galleryImages.length,
itemBuilder: (context, index) =>
_GalleryCard(imageUrl: _galleryImages[index]),
),
),
);
},
),
);
}
}
class _GalleryCard extends StatelessWidget {
const _GalleryCard({required this.imageUrl});
final String imageUrl;
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
return Container(
width: constraints.maxWidth,
height: constraints.maxHeight,
decoration: BoxDecoration(
color: AppColors.surfaceAlt,
borderRadius: BorderRadius.circular(24),
border: Border.all(color: AppColors.border, width: 1),
boxShadow: [
BoxShadow(
color: AppColors.shadowMedium,
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(24),
child: CachedNetworkImage(
imageUrl: imageUrl,
fit: BoxFit.cover,
placeholder: (_, __) => Container(
color: AppColors.surfaceAlt,
),
errorWidget: (_, __, ___) => Container(
color: AppColors.surfaceAlt,
),
),
),
);
},
);
}
}