Foggy day
[Flutter] Flutter web에서 마우스 드래그 허용, MaterialScrollBehavior/ScrollBehavior, ScrollPhysics 본문
[Flutter] Flutter web에서 마우스 드래그 허용, MaterialScrollBehavior/ScrollBehavior, ScrollPhysics
jinhan38 2024. 5. 24. 02:05이번 포스팅에서는 Flutter web에서 마우스 드래그를 허용하는 방법과 MaterialScrollBehavior, ScrollBehavior에 대해 알아보겠습니다.
1. CustomScrollBehavior
2. MaterialScrollBehavior
3. ScrollPhysics
1. CustomScrollBehavior
Flutter웹에서 마우스 드래그가 안 되는 이유는 기본 세팅값에 mouse 드래그 허용 타입이 빠져있기 때문입니다. 때문에 MaterialScrollBehavior(extends ScrollBehavior)를 커스텀해서 PointerDeviceKind 타입에 mouse를 추가해주면 드래그가 가능합니다.
PointerDeviceKind에 대해 좀 더 자세하게 들여보겠습니다. enum 클래스인 PointerDeviceKind에는 6개의 타입이 있습니다(touch, mouse, stylus, invertedStylus, trackpad, unknown). 그리고 ScrollBehavior에서 PointerDeviceKind 값을 가지고 있는 변수는 dragDevices입니다. dragDevices의 초기 값인 _kTouchLikeDeviceTypes( scroll_configuration.dart) 변수에는 6개의 타입 중 mouse만 빠져 있습니다. 그래서 dragDevices getter를 override해서 mouse 타입을 추가하는 것입니다.
Full code
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CustomScrollBehavior',
scrollBehavior: CustomScrollBehavior(),
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(width: 200, height: 300, color: Colors.red),
Container(
width: 200, height: 300, color: Colors.blue),
Container(
width: 200, height: 300, color: Colors.green),
Container(
width: 200, height: 300, color: Colors.purple),
Container(
width: 200, height: 300, color: Colors.orange),
Container(
width: 200, height: 300, color: Colors.yellow),
Container(
width: 200, height: 300, color: Colors.teal),
Container(
width: 200, height: 300, color: Colors.grey),
Container(
width: 200, height: 300, color: Colors.brown),
Container(
width: 200, height: 300, color: Colors.amber),
],
),
),
),
);
}
}
/// 마우스로 드래그 안 될 때
class CustomScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
2. MaterialScrollBehavior
MaterialScrollBehavior는 ScrollBehavior의 자식 클래스로 스크롤이 가능한 위젯의 동작 방식을 결정합니다. MaterialScrollBehavior를 처음 접하는 분들이 많을 것 같습니다. 하지만 Flutter를 사용하는 대부분의 개발자들은 인지하지 못한 채 MaterialScrollBehavior를 사용하고 있었습니다. MaterialApp 위젯의 build 함수에서 MaterialScrollBehavior를 사용하고 있었습니다.
MaterialScrollBehavior에서는 3개의 함수를 override하고 있습니다.
- getPlatform
TargetPlatform enum class 를 return하며 현재 Flutter application이 어떤 플랫폼에서 동작하는 알 수 있습니다. android, iOS, fuchsia, linux, macOS, windows 6개의 타입이 존재합니다. 만약에 Flutter web이 윈도우에서 돌아갈 경우 windows, mac에서 돌아갈 경우 macOS값을 반환합니다. - buildScrollbar
Scrollable한 위젯에 Scrollbar를 입혀주는 함수입니다. linux, macOS, windows의 platform에서는 Scrollbar를 보여주고 있습니다. android, fuchsia, iOS에서는 Scrollbar를 추가하지 않았습니다. 그래서 우리가 android나 iOS 앱을 개발할 때 스크롤바를 보여주기 위해서는 Scrollable한 위젯을 따로 Scrollbar 위젯으로 감싸줘야 했던 것입니다. - buildOverscrollIndicator
여기서는 android인 경우에만 다른 조건을 설정하고 있습니다. android 플랫폼이고 useMaterial3를 true로 한 경우 StretchingOverscrollIndicator를 반환합니다. 그렇지 않은 경우에는 GlowingOverscrollIndicator를 사용합니다. 그 외의 플랫폼들에서는 child위젯을 그대로 반환합니다.
StretchingOverscrollIndicator은 끝에 도달 했을 때 화면의 위젯들이 고무줄처럼 약간 늘어났다가 돌아오는, stretching하는 효과를 줍니다. GlowingOverscrollIndicator는 반투명한 물결을 보여줍니다.
3. ScrollPhysics
스크롤링에 대한 이벤트를 정의하는 또 다른 특성은 ScrollPhysics클래스입니다. ScrollPhysics는 ios와 macos에는 BouncingScrollPhysics를, 그 외의 플랫폼에는 ClampingScrollPhysics를 사용합니다.
GlowingOverscrollIndicator는 android에서 ClampingScrollPhysics을 사용할 때 동작을 설정하는 역할을 합니다. showLeading의 값을 false로 하면 상단에서는 이펙트가 동작 안하고, showTrailing을 false로 하면 하단에서 이펙트가 동작 안 합니다. color값을 수정하면 물결의 컬러가 변경됩니다.
'Flutter > Flutter 기타' 카테고리의 다른 글
[Flutter] Image cache(precacheImage)와 WidgetsFlutterBinding, PaintingBinding (0) | 2024.05.16 |
---|---|
[Flutter] different roots error 해결 (0) | 2023.10.26 |
[Flutter] CORS debug 모드에서 해제 처리 (0) | 2023.10.02 |
[Dart] 위경도를 TM좌표 변환하기 (0) | 2023.08.31 |
[Flutter] MethodChannel - IOS (0) | 2023.08.30 |