Flutter에서 두 개의 이미지를 겹쳐놓고 슬라이드하여 왼쪽 또는 오른쪽 이미지를 비교할 수 있는 UI를 구현하는 방법을 소개합니다. 이 글에서는 GestureDetector와 Stack 위젯을 사용하여 두 개의 이미지를 슬라이드할 수 있도록 하며, 사용자가 이미지를 슬라이드할 때 왼쪽 이미지와 오른쪽 이미지가 교차하도록 합니다.
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: Size(375, 812),
builder: () => MaterialApp(
home: ImageSlideScreen(),
),
);
}
}
class ImageSlideScreen extends StatefulWidget {
@override
_ImageSlideScreenState createState() => _ImageSlideScreenState();
}
class _ImageSlideScreenState extends State<ImageSlideScreen> {
double _sliderValue = 0.5;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Slider'),
),
body: Center(
child: GestureDetector(
onHorizontalDragUpdate: (details) {
setState(() {
_sliderValue += details.primaryDelta! / MediaQuery.of(context).size.width;
_sliderValue = _sliderValue.clamp(0.0, 0.8); // 최대치를 0.8로 제한
});
},
child: Stack(
children: [
// Background Image (Right Image)
Container(
padding: EdgeInsets.all(15),
alignment: Alignment.topRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("After", style: TextStyle(color: Colors.black), textAlign: TextAlign.right),
],
),
width: 95.w,
height: 30.h,
color: Colors.limeAccent,
),
// Foreground Image (Left Image)
ClipRect(
child: Align(
alignment: Alignment.centerLeft,
widthFactor: _sliderValue,
child: Container(
padding: EdgeInsets.all(15),
alignment: Alignment.topRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Before", style: TextStyle(color: Colors.black), textAlign: TextAlign.right),
],
),
width: 95.w,
height: 30.h,
color: Colors.pinkAccent,
),
),
),
// Center Button
Align(
alignment: Alignment.centerLeft,
child: FractionallySizedBox(
widthFactor: _sliderValue,
child: Container(
alignment: Alignment.centerRight,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
_sliderValue += details.delta.dx / MediaQuery.of(context).size.width;
_sliderValue = _sliderValue.clamp(0.0, 0.8); // 최대치를 0.8로 제한
});
},
child: CircleAvatar(
radius: 20,
backgroundColor: Colors.white,
child: Icon(Icons.compare_arrows, color: Colors.black),
),
),
),
),
),
],
),
),
),
);
}
}
ScreenUtilInit을 사용하여 반응형 디자인을 설정합니다. 이를 통해 다양한 화면 크기에 대응할 수 있습니다.
_sliderValue 변수를 통해 슬라이드 위치를 관리합니다. 기본값은 0.5로 설정하여 초기 상태에서 이미지가 반반씩 보이도록 합니다.
GestureDetector의 onHorizontalDragUpdate 콜백을 사용하여 사용자가 수평 드래그를 할 때마다 _sliderValue를 업데이트합니다. 이때, _sliderValue가 0.0에서 0.8 사이로 제한되도록 합니다.
Stack 위젯을 사용하여 두 개의 이미지를 겹칩니다. 오른쪽 이미지는 Container 위젯을 사용하여 배치하고, 왼쪽 이미지는 ClipRect와 Align을 사용하여 슬라이드 값에 따라 보이는 부분을 조절합니다.
중앙 버튼은 Align과 FractionallySizedBox를 사용하여 배치합니다. GestureDetector의 onPanUpdate를 사용하여 버튼을 슬라이드할 때 _sliderValue를 업데이트합니다. CircleAvatar를 사용하여 중앙 버튼을 구현하고, Icons.compare_arrows 아이콘을 설정합니다.
위 코드를 실행하면 두 개의 이미지가 겹쳐져 있고, 사용자가 중앙 버튼을 슬라이드할 때 왼쪽 또는 오른쪽 이미지가 보이도록 동작합니다. 이를 통해 사용자는 Before/After 이미지를 직관적으로 비교할 수 있습니다.
이와 같은 슬라이드 가능한 이미지 비교 뷰는 Before/After 비교, 제품 비교 등 다양한 용도로 활용될 수 있습니다.