import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:puzzleweave/collection/detail_dialog.dart'; import 'package:puzzleweave/config/device.dart'; import 'package:puzzleweave/l10n/app_localizations.dart'; import 'package:puzzleweave/models/items.dart'; import 'package:puzzleweave/play/board_play.dart'; import 'package:puzzleweave/skin/skin.dart'; import 'package:provider/provider.dart'; class GridItem extends StatefulWidget { final ListItem item; final bool lock; final int index; const GridItem({super.key, required this.item, required this.lock, required this.index}); @override State createState() { return _GridItemState(); } } class _GridItemState extends State { @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Stack( children: [ Hero( tag: widget.item.id, child: Material( color: Colors.transparent, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), elevation: 1, clipBehavior: Clip.hardEdge, child: Listener( child: GestureDetector( onTapUp: (details) { if (widget.lock) { Fluttertoast.showToast( msg: AppLocalizations.of(context)!.collectionLocked, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 1, backgroundColor: SkinHelper.slotBorderColor, textColor: Colors.white, fontSize: 16.0, ); } else { PageRouteBuilder? pageRouteBuilder = BoardPlay.buildRoute(widget.item); Navigator.push(context, pageRouteBuilder); } }, child: LayoutBuilder( builder: (context, constraints) { if (widget.lock) { return _buildLockedPlaceholder(constraints.biggest); } else { return _buildImage(constraints.biggest); } }, ), ), ), ), ), ], ); } String get badgeStr => '${widget.index * 25 + 1}-${(widget.index + 1) * 25}'; Widget _buildImage(Size size) { final device = context.read(); int cacheWidth = (size.width * device.realPixelRatio).toInt(); int cacheHeight = (size.height * device.realPixelRatio).toInt(); if (widget.item is AssetItem) { AssetItem assetItem = widget.item as AssetItem; return Image.asset(assetItem.thumb, cacheWidth: cacheWidth, cacheHeight: cacheHeight); } else { return network(widget.item, size.width, size.height, cacheWidth, cacheHeight); } } Widget network(ListItem item, double width, double height, int cacheWidth, int cacheHeight) { return CachedNetworkImage( imageUrl: item.thumb, fit: BoxFit.fill, width: width, height: height, memCacheWidth: cacheWidth, memCacheHeight: cacheHeight, // placeholder: (context, url) => JigsawPiece.placeHolder(scale: 0.6), ); } Widget _buildLockedPlaceholder(Size size) { return Container( width: size.width, height: size.height, decoration: BoxDecoration(color: SkinHelper.slotBorderColor, borderRadius: BorderRadius.circular(8)), child: const Center( child: Icon( Icons.lock, size: 60, // 锁图标大小 color: Colors.white, // 锁图标颜色 ), ), ); } }