[063] 플러터 (Flutter) 배우기 - 포토뷰(photo_view)로 사진 확대, 축소 기능 위젯 만들기 & PageView.builder 사용

2023. 5. 27. 21:58모바일어플개발/Flutter

반응형

안녕하세요~ totally 개발자입니다.

 

photo_view

 

어플을 개발하다보면 사진을 올리고 그 사진을 볼 수 있도록 탭해서 사진을 확대, 축소할 수 있는 기능이 필요한 경우가 있습니다. 그런 경우에 사용할 수 있는 패키지로 photo_view를 사용할 수 있습니다. 패키지 버전이 초기 버전이기는 하지만 간단하게 사용할 수 있기 때문에 활용해보면 좋습니다. 먼저 3장의 이미지를 준비해주셔야 합니다 (pixabay를 활용했습니다)

 

Step 1: pubspec.yaml에 photo_view를 설치해주시고 flutter pub get 해줍니다.

 

 

Step 2: 먼저 사진을 탭했을 때 보여주는 photoView.dart 파일을 하나 생성해주시고 코드를 작성해줍니다. 전체 코드는 맨 아래에 있으니 참고하시기 바랍니다. 여기에서 5~8번째 줄에 변수들을 선언하시고 추후 arguments로 패스할 수 있도록 합니다. 15번째 줄에 보시면 PageController 인스턴스 변수도 만들어주시고 18번째 줄에 인스턴스화 해줍니다. 여기에서 initialPage 매개변수를 currentIndex를 주셔서 어떤 사진을 클릭했는지를 알 수 있도록 전달해 주시면 됩니다.

 

 

Step 3: 그 다음 여러 장의 사진을 좌우로 스크롤하며 볼 수 있도록 만들어주는 PageView.builder를 먼저 작성하시고 그 다음 제가 아래 빨간색, 연두색, 노랑색으로 표시한 부분들을 작성합니다. 빨간 색의 PhotoView 위젯은 사진을 표시하는 위젯, 연두색 부분은 사진을 보고 닫을 수 있는 버튼, 노랑색 부분은 현재 슬라이드 위치를 표시하는 Indicator 역할을 합니다.

 

 

Step 4: main.dart 부분에 다음처럼 작성합니다.여기에서 28~32번째 줄에서는 image 링크 리스트를 만들어주시고 39번째 줄에 ListView.builder를 통해 이미지들을 쭉 세로로 보여줍니다. 그리고 그 화면을 탭했을 때 위에서 만든 PhotoViewPage로 넘어갈 수 있도록 GestureDetector를 통해 구현해줍니다. 만약 Gesture 부분을 자동으로 하고 싶은 경우에는 PhotoViewGallery 위젯을 사용하셔서 구현할 수도 있습니다. (PhotoViewGallery.builder 형태)

 

 

Step 5: 테스트해본 모습입니다.

 

 

 

[전체 소스 코드]

 

[photoView.dart]

 

import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
class PhotoViewPage extends StatefulWidget {
List<String> imagePaths;
int currentIndex;
PhotoViewPage(
{super.key, required this.imagePaths, required this.currentIndex});
@override
State<PhotoViewPage> createState() => _PhotoViewPageState();
}
class _PhotoViewPageState extends State<PhotoViewPage> {
late PageController _controller;
@override
Widget build(BuildContext context) {
_controller = PageController(initialPage: widget.currentIndex);
return Scaffold(
body: PageView.builder(
controller: _controller,
itemCount: 3,
itemBuilder: (context, index) {
return Stack(
children: [
PhotoView(
imageProvider: NetworkImage(widget.imagePaths[index]),
),
Align(
alignment: Alignment.topRight,
child: Container(
margin: const EdgeInsets.only(top: 45, right: 20),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white24,
),
child: IconButton(
icon: const Icon(
Icons.close,
color: Colors.white,
),
onPressed: () => Navigator.of(context).pop(),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: const EdgeInsets.only(bottom: 30),
child: Text(
"${index + 1} / ${widget.imagePaths.length}",
style: const TextStyle(color: Colors.white),
),
),
)
],
);
}),
);
}
}

 

[main.dart]

 

import 'package:flutter/material.dart';
import 'package:project/photoView.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter App',
home: MainPage(),
);
}
}
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List<String> imagePaths = [
'https://cdn.pixabay.com/photo/2023/04/30/09/43/flower-7960192_1280.jpg',
'https://cdn.pixabay.com/photo/2023/04/30/22/01/ocean-7961695_1280.jpg',
'https://cdn.pixabay.com/photo/2023/05/21/07/59/iceberg-8008071_1280.jpg'
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('My App'),
),
body: ListView.builder(
itemCount: imagePaths.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return PhotoViewPage(
imagePaths: imagePaths, currentIndex: index);
}));
},
child: Image(
image: NetworkImage(imagePaths[index]),
),
);
},
));
}
}
view raw 063_main.dart hosted with ❤ by GitHub

 

References:

https://pub.dev/packages/photo_view

 

photo_view | Flutter Package

Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interactive images and other stuff such as SVG.

pub.dev

 

[유튜브 강좌 영상]

 

https://youtu.be/LUvl_3wNyGk

 

반응형