gesture_config_regression_test.dart 5.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 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/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

class TestResult {
  bool dragStarted = false;
  bool dragUpdate = false;
}

16 17
class NestedScrollableCase extends StatefulWidget {
  const NestedScrollableCase({Key? key, required this.testResult}) : super(key: key);
18 19 20 21

  final TestResult testResult;

  @override
22
  State<NestedScrollableCase> createState() => _NestedScrollableCaseState();
23 24
}

25
class _NestedScrollableCaseState extends State<NestedScrollableCase> {
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

  @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) {
                      widget.testResult.dragStarted = true;
                    },
                    onVerticalDragUpdate: (DragUpdateDetails details){
                      widget.testResult.dragUpdate = true;
                    },
                    onVerticalDragEnd: (_) {},
                    child: Text('List Item $index', key: ValueKey<int>(index),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
class NestedDragableCase extends StatefulWidget {
  const NestedDragableCase({Key? key, required this.testResult}) : super(key: key);

  final TestResult testResult;

  @override
  State<NestedDragableCase> createState() => _NestedDragableCaseState();
}

class _NestedDragableCaseState extends State<NestedDragableCase> {

  @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: () {
                      widget.testResult.dragStarted = true;
                    },
                    onDragUpdate: (DragUpdateDetails details){
                      widget.testResult.dragUpdate = true;
                    },
                    onDragEnd: (_) {},
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

104 105 106 107 108 109 110 111 112
void main() {
  testWidgets('Scroll Views get the same ScrollConfiguration as GestureDetectors', (WidgetTester tester) async {
    tester.binding.window.viewConfigurationTestValue = const ui.ViewConfiguration(
      gestureSettings: ui.GestureSettings(physicalTouchSlop: 4),
    );
    final TestResult result = TestResult();

    await tester.pumpWidget(MaterialApp(
      title: 'Scroll Bug',
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
      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);
  });

  testWidgets('Scroll Views get the same ScrollConfiguration as Draggables', (WidgetTester tester) async {
    tester.binding.window.viewConfigurationTestValue = const ui.ViewConfiguration(
      gestureSettings: ui.GestureSettings(physicalTouchSlop: 4),
    );
    final TestResult result = TestResult();

    await tester.pumpWidget(MaterialApp(
      title: 'Scroll Bug',
      home: NestedDragableCase(testResult: result),
137 138 139 140 141 142 143 144 145 146 147 148 149 150
    ));

    // 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);
  });
}