V1 - Personal Account and Budgeting Done
Personal Account and Budgeting
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AttachmentGalleryScreen extends StatefulWidget {
|
||||
final List<ImageProvider> images;
|
||||
final int initialIndex;
|
||||
|
||||
const AttachmentGalleryScreen({
|
||||
super.key,
|
||||
required this.images,
|
||||
required this.initialIndex,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AttachmentGalleryScreen> createState() => _AttachmentGalleryScreenState();
|
||||
}
|
||||
|
||||
class _AttachmentGalleryScreenState extends State<AttachmentGalleryScreen> {
|
||||
late PageController _pageController;
|
||||
int _currentIndex = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_currentIndex = widget.initialIndex;
|
||||
_pageController = PageController(initialPage: widget.initialIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.black,
|
||||
iconTheme: const IconThemeData(color: Colors.white),
|
||||
title: Text(
|
||||
'${_currentIndex + 1} / ${widget.images.length}',
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
body: PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
},
|
||||
itemCount: widget.images.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _ZoomableImage(image: widget.images[index]);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ZoomableImage extends StatefulWidget {
|
||||
final ImageProvider image;
|
||||
const _ZoomableImage({required this.image});
|
||||
|
||||
@override
|
||||
State<_ZoomableImage> createState() => _ZoomableImageState();
|
||||
}
|
||||
|
||||
class _ZoomableImageState extends State<_ZoomableImage> with SingleTickerProviderStateMixin {
|
||||
final TransformationController _transformationController = TransformationController();
|
||||
late AnimationController _animationController;
|
||||
Animation<Matrix4>? _animation;
|
||||
TapDownDetails? _doubleTapDetails;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_animationController = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
)..addListener(() {
|
||||
if (_animation != null) {
|
||||
_transformationController.value = _animation!.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_animationController.dispose();
|
||||
_transformationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _handleDoubleTap() {
|
||||
if (_doubleTapDetails == null) return;
|
||||
final position = _doubleTapDetails!.localPosition;
|
||||
|
||||
final matrix = _transformationController.value;
|
||||
final scale = matrix.getMaxScaleOnAxis();
|
||||
|
||||
Matrix4 endMatrix;
|
||||
if (scale > 1.0) {
|
||||
// Zoom out
|
||||
endMatrix = Matrix4.identity();
|
||||
} else {
|
||||
// Zoom in
|
||||
endMatrix = Matrix4.identity()
|
||||
..translate(-position.dx * 1.5, -position.dy * 1.5)
|
||||
..scale(2.5);
|
||||
}
|
||||
|
||||
_animation = Matrix4Tween(
|
||||
begin: _transformationController.value,
|
||||
end: endMatrix,
|
||||
).animate(CurveTween(curve: Curves.easeInOut).animate(_animationController));
|
||||
|
||||
_animationController.forward(from: 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onDoubleTapDown: (d) => _doubleTapDetails = d,
|
||||
onDoubleTap: _handleDoubleTap,
|
||||
child: InteractiveViewer(
|
||||
transformationController: _transformationController,
|
||||
minScale: 1.0,
|
||||
maxScale: 4.0,
|
||||
child: Image(
|
||||
image: widget.image,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user