import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:keyboard/base/base_page.dart'; import 'package:keyboard/data/bean/image_viewer_item.dart'; import 'package:keyboard/resource/colors.gen.dart'; import 'package:keyboard/resource/string.gen.dart'; import 'package:keyboard/router/app_page_arguments.dart'; import 'package:keyboard/router/app_pages.dart'; import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import '../../../resource/assets.gen.dart'; import 'image_viewer_controller.dart'; /// 图片预览页 class ImageViewerPage extends BasePage { const ImageViewerPage({super.key}); /// 跳转 /// [imageViewerItemList] 图片预览数据列表 /// [index] 当前预览的索引,默认为0 static void start( List imageViewerItemList, { int index = 0, }) { Map args = { AppPageArguments.imageViewerItemList: imageViewerItemList, AppPageArguments.index: index, }; Get.toNamed(RoutePath.imageViewer, arguments: args); } @override backgroundColor() => ColorName.black; @override immersive() { // 沉浸式页面 return true; } @override bool statusBarDarkFont() { // 状态栏,白色字体 return false; } @override Widget buildBody(BuildContext context) { return Scaffold( backgroundColor: backgroundColor(), body: Stack( children: [ // 预览图 Obx(() { return PhotoViewGallery.builder( // 滚动特性 scrollPhysics: const BouncingScrollPhysics(), // 页面数量 itemCount: controller.imageViewerItemList.length, // 禁止旋转 enableRotation: false, loadingBuilder: (context, event) => Center( child: SizedBox( width: 20.0, height: 20.0, child: CircularProgressIndicator( value: event == null ? 0 : event.cumulativeBytesLoaded / (event.expectedTotalBytes ?? 0), ), ), ), onPageChanged: (index) { // 更新当前索引 controller.updateCurrentIndex(index); }, builder: (BuildContext context, int index) { return PhotoViewGalleryPageOptions.customChild( onTapDown: (context, details, controllerValue) { // 切换标题栏的显示和隐藏 controller.toggleShowTitleBar(); }, minScale: PhotoViewComputedScale.contained, maxScale: PhotoViewComputedScale.covered * 2, initialScale: PhotoViewComputedScale.contained * 0.8, // 自定义视图 child: _buildImageViewerItem(index), ); }, // backgroundDecoration: BoxDecoration(color: ColorName.black), pageController: controller.pageController, ); }), // 指示器 Visibility( visible: false, child: Positioned( left: 0, right: 0, bottom: 40.h, child: Obx(() { return _buildIndicator(); }), ), ), // 标题栏 Positioned( left: 0, top: 0, right: 0, child: Column(children: [_buildStatusBar(), _buildTitleBar()]), ), ], ), ); } /// 构建每一项 Widget _buildImageViewerItem(int index) { return Stack( fit: StackFit.expand, children: [ Image( image: controller.getImageProvider( controller.imageViewerItemList[index], ), // fit: BoxFit.cover, ), ], ); } /// 指示器 Widget _buildIndicator() { return Center( child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( '${controller.currentIndex.value + 1}/${controller.imageViewerItemList.length}', style: TextStyle( color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.w500, ), ), ], ), ); } /// 状态栏占位 Widget _buildStatusBar() { double statusBarHeight = MediaQuery.of(Get.context!).padding.top; return Container( // 导航栏高度 height: statusBarHeight, color: backgroundColor(), ); } /// 标题栏 Widget _buildTitleBar() { return Obx(() { return Visibility( visible: controller.isShowTitleBar.value, child: Container( height: kToolbarHeight, // 宽度,匹配父组件 width: double.infinity, color: ColorName.black, padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 14.0), child: Stack( children: [ // 返回按钮 GestureDetector( onTap: controller.clickBack, child: Assets.images.iconImageViewerClose.image( width: 24.w, height: 24.h, ), ), // 标题 Positioned( left: 0, top: 0, right: 0, child: Container( alignment: Alignment.center, child: Text( StringName.preview, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, color: ColorName.white, ), ), ), ), ], ), ), ); }); } }