gesture_config_regression_test.dart 4.66 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui' as ui;

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

10 11 12
class TestResult {
  bool dragStarted = false;
  bool dragUpdate = false;
13
  bool dragEnd = false;
14 15
}

16
class NestedScrollableCase extends StatelessWidget {
17
  const NestedScrollableCase({super.key, required this.testResult});
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

  final TestResult testResult;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverFixedExtentList(
            itemExtent: 50.0,
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  child: GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    onVerticalDragDown: (DragDownDetails details) {
35
                      testResult.dragStarted = true;
36 37
                    },
                    onVerticalDragUpdate: (DragUpdateDetails details){
38
                      testResult.dragUpdate = true;
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
                    },
                    onVerticalDragEnd: (_) {},
                    child: Text('List Item $index', key: ValueKey<int>(index),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

Lioness100's avatar
Lioness100 committed
54 55
class NestedDraggableCase extends StatelessWidget {
  const NestedDraggableCase({super.key, required this.testResult});
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

  final TestResult testResult;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverFixedExtentList(
            itemExtent: 50.0,
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  child: Draggable<Object>(
                    key: ValueKey<int>(index),
                    feedback: const Text('Dragging'),
                    child: Text('List Item $index'),
                    onDragStarted: () {
75
                      testResult.dragStarted = true;
76 77
                    },
                    onDragUpdate: (DragUpdateDetails details){
78
                      testResult.dragUpdate = true;
79
                    },
80 81 82
                    onDragEnd: (_) {
                      testResult.dragEnd = true;
                    },
83 84 85 86 87 88 89 90 91 92 93
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

94
void main() {
95
  testWidgets('Scroll Views get the same ScrollConfiguration as GestureDetectors', (WidgetTester tester) async {
96 97 98
    tester.view.gestureSettings = const ui.GestureSettings(physicalTouchSlop: 4);
    addTearDown(tester.view.reset);

99 100 101 102
    final TestResult result = TestResult();

    await tester.pumpWidget(MaterialApp(
      title: 'Scroll Bug',
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
      home: NestedScrollableCase(testResult: result),
    ));

    // By dragging the scroll view more than the configured touch slop above but less than
    // the framework default value, we demonstrate that this causes gesture detectors
    // that do not receive the same gesture settings to fire at different times than would
    // be expected.
    final Offset start = tester.getCenter(find.byKey(const ValueKey<int>(1)));
    await tester.timedDragFrom(start, const Offset(0, 5), const Duration(milliseconds: 50));
    await tester.pumpAndSettle();

   expect(result.dragStarted, true);
   expect(result.dragUpdate, true);
  });

118
  testWidgets('Scroll Views get the same ScrollConfiguration as Draggables', (WidgetTester tester) async {
119 120
    tester.view.gestureSettings = const ui.GestureSettings(physicalTouchSlop: 4);
    addTearDown(tester.view.reset);
121

122 123 124 125
    final TestResult result = TestResult();

    await tester.pumpWidget(MaterialApp(
      title: 'Scroll Bug',
Lioness100's avatar
Lioness100 committed
126
      home: NestedDraggableCase(testResult: result),
127 128 129 130 131 132 133 134 135 136 137 138
    ));

    // By dragging the scroll view more than the configured touch slop above but less than
    // the framework default value, we demonstrate that this causes gesture detectors
    // that do not receive the same gesture settings to fire at different times than would
    // be expected.
    final Offset start = tester.getCenter(find.byKey(const ValueKey<int>(1)));
    await tester.timedDragFrom(start, const Offset(0, 5), const Duration(milliseconds: 50));
    await tester.pumpAndSettle();

   expect(result.dragStarted, true);
   expect(result.dragUpdate, true);
139
   expect(result.dragEnd, true);
140 141
  });
}