Foggy day

[Flutter] Flutter web에서 마우스 드래그 허용, MaterialScrollBehavior/ScrollBehavior, ScrollPhysics 본문

Flutter/Flutter 기타

[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하고 있습니다.

 

 

  1. getPlatform
    TargetPlatform enum class 를 return하며 현재 Flutter application이 어떤 플랫폼에서 동작하는 알 수 있습니다. android, iOS, fuchsia, linux, macOS, windows 6개의 타입이 존재합니다. 만약에 Flutter web이 윈도우에서 돌아갈 경우 windows, mac에서 돌아갈 경우 macOS값을 반환합니다. 
  2. buildScrollbar
    Scrollable한 위젯에 Scrollbar를 입혀주는 함수입니다. linux, macOS, windows의 platform에서는 Scrollbar를 보여주고 있습니다. android, fuchsia, iOS에서는 Scrollbar를 추가하지 않았습니다. 그래서 우리가 android나 iOS 앱을 개발할 때 스크롤바를 보여주기 위해서는 Scrollable한 위젯을 따로 Scrollbar 위젯으로 감싸줘야 했던 것입니다.
  3. 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값을 수정하면 물결의 컬러가 변경됩니다.