Что такое Hit Test в Flutter?

«Что такое Hit Test в Flutter?» — вопрос из категории Рендеринг и производительность, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Hit Test (или тест на попадание) в Flutter — это механизм, который определяет, какой виджет в дереве должен получить пользовательское событие (касание, нажатие, прокрутка). Процесс проходит сверху вниз: от корневого виджета (RenderView) к листовым, проверяя, попадает ли точка касания в область каждого виджета и может ли он обработать это событие.

Как это работает на практике:

Stack(
  children: [
    // Этот Container будет перехватывать касания, даже если он прозрачный
    GestureDetector(
      onTap: () => print('Background tapped'),
      child: Container(color: Colors.transparent),
    ),
    // Этот виджет поверх, но он может быть исключен из Hit Test
    IgnorePointer(
      ignoring: true, // Исключает виджет и его детей из Hit Test
      child: Container(
        width: 100,
        height: 100,
        color: Colors.red,
        child: GestureDetector(
          onTap: () => print('This will never print'), // Не сработает
          child: Text('Click me'),
        ),
      ),
    ),
  ],
)

Ключевые аспекты Hit Test:

  • Порядок: Обработка идет в порядке отрисовки (сверху вниз для Stack).
  • Участие виджета: Виджет может контролировать свое участие через поведение своего RenderObject (методы hitTestSelf и hitTestChildren).
  • Управление: Виджеты IgnorePointer и AbsorbPointer позволяют явно исключать поддерево из теста на попадание, что полезно для отключения интерактивности или создания оверлеев, которые не блокируют события.

Понимание Hit Test критично для создания кастомных жестов, корректной работы наложений (Stack, Positioned) и отладки проблем, когда виджет "не кликается".