list_view_misc_test.dart 7.38 KB
Newer Older
Hixie's avatar
Hixie committed
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Adam Barth's avatar
Adam Barth committed
5
import 'package:flutter_test/flutter_test.dart';
6
import 'package:flutter/rendering.dart';
7
import 'package:flutter/widgets.dart';
Hixie's avatar
Hixie committed
8

9
const Key blockKey = const Key('test');
Hixie's avatar
Hixie committed
10 11

void main() {
12 13
  testWidgets('Cannot scroll a non-overflowing block', (WidgetTester tester) async {
    await tester.pumpWidget(
14 15 16 17 18 19 20 21 22 23 24 25
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          key: blockKey,
          children: <Widget>[
            new Container(
              height: 200.0, // less than 600, the height of the test area
              child: const Text('Hello'),
            ),
          ],
        ),
      ),
26 27
    );

28 29
    final Offset middleOfContainer = tester.getCenter(find.text('Hello'));
    final Offset target = tester.getCenter(find.byKey(blockKey));
30
    final TestGesture gesture = await tester.startGesture(target);
31
    await gesture.moveBy(const Offset(0.0, -10.0));
32

33
    await tester.pump(const Duration(milliseconds: 1));
34 35 36

    expect(tester.getCenter(find.text('Hello')) == middleOfContainer, isTrue);

37
    await gesture.up();
Hixie's avatar
Hixie committed
38 39
  });

40 41
  testWidgets('Can scroll an overflowing block', (WidgetTester tester) async {
    await tester.pumpWidget(
42 43 44 45 46 47 48 49 50 51 52 53
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          key: blockKey,
          children: <Widget>[
            new Container(
              height: 2000.0, // more than 600, the height of the test area
              child: const Text('Hello'),
            ),
          ],
        ),
      ),
54
    );
55

56 57 58
    final Offset middleOfContainer = tester.getCenter(find.text('Hello'));
    expect(middleOfContainer.dx, equals(400.0));
    expect(middleOfContainer.dy, equals(1000.0));
59

60
    final Offset target = tester.getCenter(find.byKey(blockKey));
61
    final TestGesture gesture = await tester.startGesture(target);
62
    await gesture.moveBy(const Offset(0.0, -10.0));
63

64
    await tester.pump(); // redo layout
65

66
    expect(tester.getCenter(find.text('Hello')), isNot(equals(middleOfContainer)));
67

68
    await gesture.up();
Hixie's avatar
Hixie committed
69
  });
70

71
  testWidgets('ListView reverse', (WidgetTester tester) async {
72 73 74
    int first = 0;
    int second = 0;

75
    Widget buildBlock({ bool reverse: false }) {
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
      return new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          key: new UniqueKey(),
          reverse: reverse,
          children: <Widget>[
            new GestureDetector(
              onTap: () { first += 1; },
              child: new Container(
                height: 350.0, // more than half the height of the test area
                color: const Color(0xFF00FF00),
              )
            ),
            new GestureDetector(
              onTap: () { second += 1; },
              child: new Container(
                height: 350.0, // more than half the height of the test area
                color: const Color(0xFF0000FF),
              ),
            ),
          ],
        ),
98 99
      );
    }
100

101
    await tester.pumpWidget(buildBlock(reverse: true));
102

103
    const Offset target = const Offset(200.0, 200.0);
104
    await tester.tapAt(target);
105 106
    expect(first, equals(0));
    expect(second, equals(1));
107

108
    await tester.pumpWidget(buildBlock(reverse: false));
109

110
    await tester.tapAt(target);
111 112
    expect(first, equals(1));
    expect(second, equals(1));
113
  });
114

115
  testWidgets('ListView controller', (WidgetTester tester) async {
116
    final ScrollController controller = new ScrollController();
117

118
    Widget buildBlock() {
119 120 121 122
      return new Directionality(
        textDirection: TextDirection.ltr,
        child: new ListView(
          controller: controller,
123
          children: const <Widget>[const Text('A'), const Text('B'), const Text('C')],
124
        ),
125 126 127
      );
    }
    await tester.pumpWidget(buildBlock());
128
    expect(controller.offset, equals(0.0));
129
  });
130

131
  testWidgets('SliverBlockChildListDelegate.estimateMaxScrollOffset hits end', (WidgetTester tester) async {
132
    final SliverChildListDelegate delegate = new SliverChildListDelegate(<Widget>[
133 134 135 136 137 138 139
      new Container(),
      new Container(),
      new Container(),
      new Container(),
      new Container(),
    ]);

140 141 142 143 144 145 146 147 148
    await tester.pumpWidget(
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new CustomScrollView(
          slivers: <Widget>[
            new SliverList(
              delegate: delegate,
            ),
          ],
149
        ),
150 151
      ),
    );
152

153
    final SliverMultiBoxAdaptorElement element = tester.element(find.byType(SliverList));
154 155 156 157 158 159 160 161 162

    final double maxScrollOffset = element.estimateMaxScrollOffset(
      null,
      firstIndex: 3,
      lastIndex: 4,
      leadingScrollOffset: 25.0,
      trailingScrollOffset: 26.0
    );
    expect(maxScrollOffset, equals(26.0));
163
  });
164 165 166 167 168 169 170 171 172 173

  testWidgets('Resizing a ListView child restores scroll offset', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/9221
    final AnimationController controller = new AnimationController(
      vsync: const TestVSync(),
      duration: const Duration(milliseconds: 200),
    );

    // The overall height of the frame is (as ever) 600
    Widget buildFrame() {
174 175 176 177 178 179 180
      return new Directionality(
        textDirection: TextDirection.ltr,
        child: new Column(
          children: <Widget>[
            new Flexible(
              // The overall height of the ListView's contents is 500
              child: new ListView(
181
                children: const <Widget>[
182 183 184 185 186
                  const SizedBox(
                    height: 150.0,
                    child: const Center(
                      child: const Text('top')
                    ),
187
                  ),
188 189 190 191 192
                  const SizedBox(
                    height: 200.0,
                    child: const Center(
                      child: const Text('middle')
                    ),
193
                  ),
194 195 196 197 198
                  const SizedBox(
                    height: 150.0,
                    child: const Center(
                      child: const Text('bottom')
                    ),
199
                  ),
200 201
                ],
              ),
202
            ),
203 204 205 206 207 208 209
            // If this widget's height is > 100 the ListView can scroll.
            new SizeTransition(
              sizeFactor: controller.view,
              child: const SizedBox(
                height: 300.0,
                child: const Text('keyboard'),
              ),
210
            ),
211 212
          ],
        ),
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
      );
    }

    await tester.pumpWidget(buildFrame());
    expect(find.text('top'), findsOneWidget);

    final ScrollPosition position = Scrollable.of(tester.element(find.text('middle'))).position;
    expect(position.viewportDimension, 600.0);
    expect(position.pixels, 0.0);

    // Animate the 'keyboard' height from 0 to 300
    controller.forward();
    await tester.pumpAndSettle();
    expect(position.viewportDimension, 300.0);

    // Scroll the ListView upwards
    position.jumpTo(200.0);
    await tester.pumpAndSettle();
    expect(position.pixels, 200.0);
    expect(find.text('top'), findsNothing);

    // Animate the 'keyboard' height back to 0. This causes the scroll
    // offset to return to 0.0
    controller.reverse();
    await tester.pumpAndSettle();
    expect(position.viewportDimension, 600.0);
    expect(position.pixels, 0.0);
    expect(find.text('top'), findsOneWidget);
  });
Hixie's avatar
Hixie committed
242
}