import 'dart:io'; import 'package:flutter/material.dart'; import 'package:cs_resources/generated/assets.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:plugin_basic/router/basic_page_router.dart'; import 'package:router/ext/auto_router_extensions.dart'; import 'package:router/path/router_path.dart'; import 'package:shared/utils/screen_util.dart'; import 'package:widgets/my_load_image.dart'; import 'package:widgets/my_text_view.dart'; import 'package:cs_resources/constants/color_constants.dart'; import 'package:extended_image/extended_image.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:auto_route/auto_route.dart'; /* * 预览的图片的页面,内部使用PageView左右切换 */ @RoutePage() class PreviewPhotoPage extends HookConsumerWidget { final List images; final int position; const PreviewPhotoPage({ Key? key, required this.images, required this.position, }) : super(key: key); //启动当前页面 static Future? startInstance({ required BuildContext context, required List images, required int position, }) { return context.router.push(PreviewPhotoPageRoute(images: images, position: position)); } @override Widget build(BuildContext context, WidgetRef ref) { final currentIndex = useState(position); return Scaffold( backgroundColor: ColorConstants.black, body: SafeArea( bottom: true, top: false, //真正的 Content 布局 child: Column( children: [ SizedBox(height: ScreenUtil.getStatusBarH(context)), Row( children: [ //间距 const SizedBox(width: 30), Expanded( child: MyTextView( "${currentIndex.value + 1}/${images.length}", textColor: Colors.white, fontSize: 18, isFontRegular: true, textAlign: TextAlign.center, ), ), InkWell( onTap: () { appRouter.maybePop(); }, child: const MyAssetImage( Assets.baseLibDialogDeleteIcon, width: 14, height: 14, ), ), //间距 const SizedBox(width: 15), ], ), Expanded( child: ExtendedImageGesturePageView.builder( controller: ExtendedPageController( //图片PageView的配置选项 initialPage: currentIndex.value, pageSpacing: 10, ), itemCount: images.length, scrollDirection: Axis.horizontal, onPageChanged: (int index) { currentIndex.value = index; }, itemBuilder: (BuildContext context, int index) { //默认网络加载的占位图 final Widget placeholder = Container( //如果没有设置占位图,使用默认的灰色背景内置Icon小图标 width: double.infinity, height: double.infinity, color: ColorConstants.greye0, alignment: Alignment.center, child: const MyAssetImage( Assets.baseLibImageDefaultPlaceholder, width: 38, height: 32, ), ); //区分网络图片和本地图片 Widget image = images[index].startsWith("http") ? ExtendedImage.network( images[index], fit: BoxFit.contain, timeLimit: const Duration(milliseconds: 30000), cache: true, mode: ExtendedImageMode.gesture, loadStateChanged: (ExtendedImageState state) { switch (state.extendedImageLoadState) { case LoadState.loading: return placeholder; case LoadState.completed: return null; case LoadState.failed: return placeholder; } }, initGestureConfigHandler: (ExtendedImageState state) { return GestureConfig( // 图片展示的配置选项 inPageView: true, initialScale: 1.0, maxScale: 5.0, animationMaxScale: 6.0, initialAlignment: InitialAlignment.center, cacheGesture: false, ); }, ) : ExtendedImage.file( File(images[index]), fit: BoxFit.contain, mode: ExtendedImageMode.gesture, initGestureConfigHandler: (ExtendedImageState state) { return GestureConfig( // 图片展示的配置选项 inPageView: true, initialScale: 1.0, maxScale: 5.0, animationMaxScale: 6.0, initialAlignment: InitialAlignment.center, cacheGesture: false, ); }, ); if (index == currentIndex.value) { return Hero( // tag: index.toString(), tag: "0", child: image, ); } else { return image; } }, )), ], ), ), ); } }