| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- import 'dart:async';
- import 'package:flutter/material.dart';
- import 'package:puzzleweave/audio/jc_audio_controller.dart';
- import 'package:puzzleweave/collection/grid_item.dart';
- import 'package:puzzleweave/config/device.dart';
- import 'package:puzzleweave/l10n/app_localizations.dart';
- import 'package:puzzleweave/models/cached_request.dart';
- import 'package:puzzleweave/models/data.dart';
- import 'package:puzzleweave/models/items.dart';
- import 'package:logging/logging.dart';
- import 'package:provider/provider.dart';
- import 'package:puzzleweave/skin/skin.dart';
- final Logger _log = Logger('collection_screen');
- class CollectionScreen extends StatefulWidget {
- const CollectionScreen({super.key});
- @override
- State<StatefulWidget> createState() => _CollectionScreen();
- static PageRouteBuilder buildRoute() {
- return PageRouteBuilder(
- pageBuilder: (context, animation, secondaryAnimation) {
- return CollectionScreen();
- },
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
- // return FadeTransition(opacity: animation, child: child);
- return SlideTransition(
- position: Tween(begin: const Offset(1, 0), end: Offset.zero).animate(animation),
- child: child,
- );
- },
- );
- }
- }
- class _CollectionScreen extends State<CollectionScreen> {
- late JcAudioController audio;
- late Data data;
- List<ListItem>? collection;
- late CachedRequest collectionCachedRequest;
- late StreamSubscription? collectionSubscription;
- @override
- void initState() {
- super.initState();
- audio = context.read<JcAudioController>();
- data = context.read<Data>();
- collectionCachedRequest = data.collection;
- // 主动获取缓存数据(关键)
- final collectionCachedData = collectionCachedRequest.cachedData;
- if (collectionCachedData != null) {
- _onCollectionDataUpdate(collectionCachedData);
- }
- collectionSubscription = collectionCachedRequest.stream.listen(_onCollectionDataUpdate, onError: _onCollectionDataError);
- }
- @override
- void dispose() {
- collectionSubscription?.cancel();
- super.dispose();
- }
- _onCollectionDataUpdate(data) async {
- _log.info('_onCollectionDataUpdate.... ');
- if (data != null) {
- collection = data as List<ListItem>;
- setState(() {});
- }
- }
- _onCollectionDataError(error) {
- _log.info('_onCollectionDataError.... $error');
- }
- Future<void> refresh() async {
- _log.info('refresh...');
- await collectionCachedRequest.refresh();
- }
- @override
- Widget build(BuildContext context) {
- final device = context.read<Device>();
- final isTablet = device.isTablet;
- return Scaffold(
- backgroundColor: SkinHelper.colorWhite,
- appBar: AppBar(
- backgroundColor: SkinHelper.colorWhite,
- // elevation: 1,
- centerTitle: true,
- leading: IconButton(
- onPressed: () {
- audio.playSfx(SfxType.click);
- Navigator.pop(context);
- },
- icon: const Icon(Icons.arrow_back_outlined, color: Colors.black87),
- ),
- title: Text(
- AppLocalizations.of(context)!.collection,
- style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 24),
- ),
- ),
- body: collection == null
- ? scrollableDummy
- : RefreshIndicator(
- onRefresh: refresh,
- child: CustomScrollView(
- slivers: <Widget>[
- // header
- SliverPadding(
- sliver: SliverGrid(
- gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: isTablet ? 300 : 210, childAspectRatio: 2 / 3),
- delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
- return _buildItem(context, index);
- }, childCount: collection!.length),
- ),
- padding: const EdgeInsets.only(left: 10.0, right: 10.0),
- ),
- ],
- ),
- ),
- );
- }
- // Widget get scrollableDummy => LayoutBuilder(
- // builder: (p0, p1) {
- // return SingleChildScrollView(
- // physics: const AlwaysScrollableScrollPhysics(),
- // child: SizedBox(
- // height: p1.maxHeight,
- // child: Center(
- // child: ListView(
- // shrinkWrap: true,
- // children: [
- // Lottie.asset('assets/lottie/loading.json', height: 100),
- // const Center(child: Text("loading...")),
- // ],
- // ),
- // ),
- // ),
- // );
- // },
- // );
- Widget get scrollableDummy => Scaffold(
- backgroundColor: SkinHelper.colorWhite,
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- // 替换 Lottie 为原生进度条
- SizedBox(width: 40, height: 40, child: CircularProgressIndicator(strokeWidth: 3, valueColor: AlwaysStoppedAnimation<Color>(SkinHelper.coreBgColor))),
- const SizedBox(height: 16),
- Text(
- "Loading...",
- style: TextStyle(color: SkinHelper.slotBorderColor.withOpacity(0.7), fontSize: 14, fontWeight: FontWeight.w500),
- ),
- ],
- ),
- ),
- );
- Widget _buildItem(context, index) {
- ListItem item = collection![index];
- final bool isLocked = index >= data.currentCollectionIndex; // 假设 currentCollectionIndex 之前是解锁的
- return Padding(
- padding: const EdgeInsets.all(10.0),
- child: CollectionGridItem(item: item, lock: isLocked, index: index),
- );
- }
- }
|