Implementation of image carousel with carousel_slider library

codemagic-setup
Hank Grabowski 2023-01-29 22:36:01 -05:00
rodzic 8fad35ed33
commit b23f45a180
3 zmienionych plików z 52 dodań i 88 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
@ -19,7 +20,7 @@ class ImageViewerScreen extends StatefulWidget {
const ImageViewerScreen({
super.key,
required this.attachments,
int this.initialIndex = 0,
this.initialIndex = 0,
});
@override
@ -27,11 +28,12 @@ class ImageViewerScreen extends StatefulWidget {
}
class _ImageViewerScreenState extends State<ImageViewerScreen> {
var index = 0;
MediaAttachment? currentAttachment;
@override
void initState() {
index = widget.initialIndex;
super.initState();
currentAttachment = widget.attachments[widget.initialIndex];
}
Future<void> saveImage(
@ -71,109 +73,62 @@ class _ImageViewerScreenState extends State<ImageViewerScreen> {
@override
Widget build(BuildContext context) {
print('Index: $index');
final attachment = widget.attachments[index];
final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;
final carouselHeight =
widget.attachments.length == 1 ? height * 0.9 : height * 0.8;
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () => saveImage(context, attachment),
onPressed: currentAttachment == null
? null
: () => saveImage(context, currentAttachment!),
icon: const Icon(Icons.download))
],
),
body: SafeArea(
child: Stack(
child: Column(
children: [
GestureDetector(
onHorizontalDragEnd: (details) {
final velocity = details.primaryVelocity ?? 0.0;
print('Velocity: $velocity');
if (velocity > 0 && index > 0) {
setState(() {
index--;
});
}
if (velocity < 0 && index < widget.attachments.length - 1) {
setState(() {
index++;
});
}
CarouselSlider.builder(
itemCount: widget.attachments.length,
itemBuilder: (context, index, realIndex) {
return SizedBox(
width: width,
height: carouselHeight,
child: InteractiveViewer(
maxScale: 10.0,
scaleFactor: 400,
child: CachedNetworkImage(
imageUrl: widget.attachments[index].uri.toString()),
),
);
},
child: buildCoreViewer(attachment),
options: CarouselOptions(
height: carouselHeight,
initialPage: widget.initialIndex,
enableInfiniteScroll: false,
enlargeCenterPage: true,
viewportFraction: 0.95,
onPageChanged: (index, reason) {
setState(() {
currentAttachment = widget.attachments[index];
});
}),
),
if (index > 0)
Positioned(
top: height / 2,
left: 0.0,
child: buildButton(
Icon(Icons.keyboard_arrow_left),
onPressed: () {
setState(() {
index--;
});
},
),
),
if (index < widget.attachments.length - 1)
Positioned(
top: height / 2,
right: 0.0,
child: buildButton(
Icon(Icons.keyboard_arrow_right),
onPressed: () {
setState(() {
index++;
});
},
),
),
if (currentAttachment != null) buildTextArea(currentAttachment!),
],
),
),
);
}
Widget buildCoreViewer(MediaAttachment attachment) {
final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: width,
height: 0.8 * height,
child: InteractiveViewer(
maxScale: 10.0,
scaleFactor: 400,
child: CachedNetworkImage(imageUrl: attachment.uri.toString()),
),
),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(attachment.description),
),
),
),
],
);
}
Widget buildButton(Icon icon, {required Function() onPressed}) {
return Center(
child: Ink(
decoration: ShapeDecoration(
color: Theme.of(context).focusColor,
shape: CircleBorder(),
),
child: IconButton(
icon: icon,
color: Colors.white,
onPressed: onPressed,
Widget buildTextArea(MediaAttachment attachment) {
return Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(attachment.description),
),
),
);

Wyświetl plik

@ -137,6 +137,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
carousel_slider:
dependency: "direct main"
description:
name: carousel_slider
sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42"
url: "https://pub.dev"
source: hosted
version: "4.2.1"
characters:
dependency: transitive
description:

Wyświetl plik

@ -42,6 +42,7 @@ dependencies:
objectbox: ^1.7.1
objectbox_flutter_libs: ^1.7.1
path_provider: ^2.0.11
carousel_slider: ^4.2.1
dev_dependencies:
flutter_test: