fixed_height_scrollable.dart 2.4 KB
Newer Older
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.

5
import 'dart:math' as math;
6

7
import 'package:vector_math/vector_math.dart';
8 9

import '../animation/scroll_behavior.dart';
10
import 'scrollable.dart';
11
import 'wrappers.dart';
12 13

abstract class FixedHeightScrollable extends Scrollable {
14

15 16 17
  FixedHeightScrollable({ this.itemHeight, Object key }) : super(key: key) {
    assert(itemHeight != null);
  }
18

19 20 21 22 23 24 25
  double itemHeight;

  void syncFields(FixedHeightScrollable source) {
    itemHeight = source.itemHeight;
    super.syncFields(source);
  }

26 27 28 29 30 31 32 33
  ScrollBehavior createScrollBehavior() => new OverscrollBehavior();
  OverscrollBehavior get scrollBehavior => super.scrollBehavior as OverscrollBehavior;

  int _itemCount = 0;
  int get itemCount => _itemCount;
  void set itemCount (int value) {
    if (_itemCount != value) {
      _itemCount = value;
34
      scrollBehavior.contentsHeight = itemHeight * _itemCount;
35 36 37
    }
  }

38
  double _height;
39
  void _handleSizeChanged(Size newSize) {
40
    setState(() {
41
      _height = newSize.height;
42
      scrollBehavior.containerHeight = _height;
43 44 45 46
    });
  }

  UINode buildContent() {
47 48
    var itemShowIndex = 0;
    var itemShowCount = 0;
49

50 51
    Matrix4 transform = new Matrix4.identity();

52
    if (_height != null && _height > 0.0) {
53 54
      if (scrollOffset < 0.0) {
        double visibleHeight = _height + scrollOffset;
55
        itemShowCount = (visibleHeight / itemHeight).round() + 1;
56
        transform.translate(0.0, -scrollOffset);
57
      } else {
58
        itemShowCount = (_height / itemHeight).ceil() + 1;
59
        double alignmentDelta = -scrollOffset % itemHeight;
60
        if (alignmentDelta != 0.0)
61
          alignmentDelta -= itemHeight;
62 63

        double drawStart = scrollOffset + alignmentDelta;
64
        itemShowIndex = math.max(0, (drawStart / itemHeight).floor());
65

66
        transform.translate(0.0, alignmentDelta);
67 68 69
      }
    }

70 71
    return new SizeObserver(
      callback: _handleSizeChanged,
72
      child: new ClipRect(
73 74 75 76 77 78
        child: new DecoratedBox(
          decoration: const BoxDecoration(
            backgroundColor: const Color(0xFFFFFFFF)
          ),
          child: new Transform(
            transform: transform,
79
            child: new Block(buildItems(itemShowIndex, itemShowCount))
80
          )
81
        )
82
      )
83 84 85 86
    );
  }

  List<UINode> buildItems(int start, int count);  
87

88
}