grid_item.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:fluttertoast/fluttertoast.dart';
  4. import 'package:puzzleweave/collection/detail_dialog.dart';
  5. import 'package:puzzleweave/config/device.dart';
  6. import 'package:puzzleweave/l10n/app_localizations.dart';
  7. import 'package:puzzleweave/models/items.dart';
  8. import 'package:puzzleweave/play/board_play.dart';
  9. import 'package:puzzleweave/skin/skin.dart';
  10. import 'package:provider/provider.dart';
  11. class GridItem extends StatefulWidget {
  12. final ListItem item;
  13. final bool lock;
  14. final int index;
  15. const GridItem({super.key, required this.item, required this.lock, required this.index});
  16. @override
  17. State<StatefulWidget> createState() {
  18. return _GridItemState();
  19. }
  20. }
  21. class _GridItemState extends State<GridItem> {
  22. @override
  23. void initState() {
  24. super.initState();
  25. }
  26. @override
  27. void dispose() {
  28. super.dispose();
  29. }
  30. @override
  31. Widget build(BuildContext context) {
  32. return Stack(
  33. children: [
  34. Hero(
  35. tag: widget.item.id,
  36. child: Material(
  37. color: Colors.transparent,
  38. shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
  39. elevation: 1,
  40. clipBehavior: Clip.hardEdge,
  41. child: Listener(
  42. child: GestureDetector(
  43. onTapUp: (details) {
  44. if (widget.lock) {
  45. Fluttertoast.showToast(
  46. msg: AppLocalizations.of(context)!.collectionLocked,
  47. toastLength: Toast.LENGTH_SHORT,
  48. gravity: ToastGravity.CENTER,
  49. timeInSecForIosWeb: 1,
  50. backgroundColor: SkinHelper.slotBorderColor,
  51. textColor: Colors.white,
  52. fontSize: 16.0,
  53. );
  54. } else {
  55. PageRouteBuilder? pageRouteBuilder = BoardPlay.buildRoute(widget.item);
  56. Navigator.push(context, pageRouteBuilder);
  57. }
  58. },
  59. child: LayoutBuilder(
  60. builder: (context, constraints) {
  61. if (widget.lock) {
  62. return _buildLockedPlaceholder(constraints.biggest);
  63. } else {
  64. return _buildImage(constraints.biggest);
  65. }
  66. },
  67. ),
  68. ),
  69. ),
  70. ),
  71. ),
  72. ],
  73. );
  74. }
  75. String get badgeStr => '${widget.index * 25 + 1}-${(widget.index + 1) * 25}';
  76. Widget _buildImage(Size size) {
  77. final device = context.read<Device>();
  78. int cacheWidth = (size.width * device.realPixelRatio).toInt();
  79. int cacheHeight = (size.height * device.realPixelRatio).toInt();
  80. if (widget.item is AssetItem) {
  81. AssetItem assetItem = widget.item as AssetItem;
  82. return Image.asset(assetItem.thumb, cacheWidth: cacheWidth, cacheHeight: cacheHeight);
  83. } else {
  84. return network(widget.item, size.width, size.height, cacheWidth, cacheHeight);
  85. }
  86. }
  87. Widget network(ListItem item, double width, double height, int cacheWidth, int cacheHeight) {
  88. return CachedNetworkImage(
  89. imageUrl: item.thumb,
  90. fit: BoxFit.fill,
  91. width: width,
  92. height: height,
  93. memCacheWidth: cacheWidth,
  94. memCacheHeight: cacheHeight,
  95. // placeholder: (context, url) => JigsawPiece.placeHolder(scale: 0.6),
  96. );
  97. }
  98. Widget _buildLockedPlaceholder(Size size) {
  99. return Container(
  100. width: size.width,
  101. height: size.height,
  102. decoration: BoxDecoration(color: SkinHelper.slotBorderColor, borderRadius: BorderRadius.circular(8)),
  103. child: const Center(
  104. child: Icon(
  105. Icons.lock,
  106. size: 60, // 锁图标大小
  107. color: Colors.white, // 锁图标颜色
  108. ),
  109. ),
  110. );
  111. }
  112. }