mirror of
https://gitlab.com/mysocialportal/relatica
synced 2024-10-18 11:13:31 +00:00
Implementation of image carousel with carousel_slider library
This commit is contained in:
parent
8fad35ed33
commit
b23f45a180
3 changed files with 52 additions and 88 deletions
|
@ -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),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue