Skip to content

[two_dimensional_scrollables] Part of rows out of viewport don't get gestures #187084

Description

@Albert221

Hey, Flutter 3.44.0, two_dimensional_scrollables 0.5.2. In TreeView, after I horizontally scroll, I cannot hit-test parts of my nodes that were out of the viewport horizontally.

Below is a minimum reproducible example

tree_horizontal_hit_repro.dart

import 'package:flutter/material.dart';
import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart';

class TreeHorizontalHitRepro extends StatefulWidget {
  const TreeHorizontalHitRepro({
    super.key,
    required this.onTap,
    this.viewportWidth = 200,
    this.blueWidth = 50,
    this.rowHeight = 40,
  });

  final void Function(String segment) onTap;
  final double viewportWidth;
  final double blueWidth;
  final double rowHeight;

  @override
  State<TreeHorizontalHitRepro> createState() =>
      _TreeHorizontalHitReproState();
}

class _TreeHorizontalHitReproState extends State<TreeHorizontalHitRepro> {
  final _controller = TreeViewController();
  final _vertical = ScrollController();
  final _horizontal = ScrollController();

  @override
  void dispose() {
    _vertical.dispose();
    _horizontal.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final tree = <TreeViewNode<int>>[TreeViewNode<int>(0)];
    return SizedBox(
      width: widget.viewportWidth,
      height: widget.rowHeight,
      child: TreeView<int>(
        controller: _controller,
        tree: tree,
        verticalDetails: ScrollableDetails.vertical(controller: _vertical),
        horizontalDetails: ScrollableDetails.horizontal(
          controller: _horizontal,
        ),
        indentation: TreeViewIndentationType.none,
        treeNodeBuilder: (context, node, _) {
          return Row(
            mainAxisSize: .min,
            children: [
              GestureDetector(
                key: const Key('red-segment'),
                behavior: HitTestBehavior.opaque,
                onTap: () => widget.onTap('red'),
                child: Container(
                  width: widget.viewportWidth,
                  height: widget.rowHeight,
                  color: Colors.red,
                ),
              ),
              GestureDetector(
                key: const Key('blue-segment'),
                behavior: HitTestBehavior.opaque,
                onTap: () => widget.onTap('blue'),
                child: Container(
                  width: widget.blueWidth,
                  height: widget.rowHeight,
                  color: Colors.blue,
                ),
              ),
            ],
          );
        },
        treeRowBuilder: (node) =>
            TreeRow(extent: FixedTreeRowExtent(widget.rowHeight)),
      ),
    );
  }
}

Test file

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'tree_horizontal_hit_repro.dart';

void main() {
  testWidgets(
    'TreeView row is fully tappable across a horizontal scroll',
    (tester) async {
      final tapped = <String>[];
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Align(
              alignment: .topLeft,
              child: TreeHorizontalHitRepro(onTap: tapped.add),
            ),
          ),
        ),
      );

      expect(find.byKey(const Key('red-segment')), findsOneWidget);
      expect(find.byKey(const Key('blue-segment')), findsOneWidget);

      await tester.tap(find.byKey(const Key('red-segment')));
      await tester.pumpAndSettle();
      expect(tapped, ['red']);

      await tester.drag(
        find.byKey(const Key('red-segment')),
        const Offset(-60, 0),
      );
      await tester.pumpAndSettle();

      await tester.tap(find.byKey(const Key('blue-segment')));
      await tester.pumpAndSettle();

      expect(tapped, ['red', 'blue']);
    },
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: two_dimensional_scrollablesIssues pertaining to the two_dimensional_scrollables packagepackageflutter/packages repository. See also p: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions