ev.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/rendering.dart';
  3. import 'dart:math' as math;
  4. class ExpandedViewport extends Viewport {
  5. ExpandedViewport({
  6. Key key,
  7. AxisDirection axisDirection = AxisDirection.down,
  8. AxisDirection crossAxisDirection,
  9. double anchor = 0.0,
  10. ScrollPosition offset,
  11. Key center,
  12. double cacheExtent,
  13. List<Widget> slivers = const <Widget>[],
  14. }) : super(
  15. key: key,
  16. slivers: slivers,
  17. axisDirection: axisDirection,
  18. crossAxisDirection: crossAxisDirection,
  19. anchor: anchor,
  20. offset: offset,
  21. center: center,
  22. cacheExtent: cacheExtent);
  23. @override
  24. RenderViewport createRenderObject(BuildContext context) {
  25. return _RenderExpandedViewport(
  26. axisDirection: axisDirection,
  27. crossAxisDirection: crossAxisDirection ??
  28. Viewport.getDefaultCrossAxisDirection(context, axisDirection),
  29. anchor: anchor,
  30. offset: offset,
  31. cacheExtent: cacheExtent,
  32. );
  33. }
  34. }
  35. class _RenderExpandedViewport extends RenderViewport {
  36. _RenderExpandedViewport({
  37. AxisDirection axisDirection = AxisDirection.down,
  38. @required AxisDirection crossAxisDirection,
  39. @required ViewportOffset offset,
  40. double anchor = 0.0,
  41. List<RenderSliver> children,
  42. RenderSliver center,
  43. double cacheExtent,
  44. }) : super(
  45. axisDirection: axisDirection,
  46. crossAxisDirection: crossAxisDirection,
  47. offset: offset,
  48. anchor: anchor,
  49. children: children,
  50. center: center,
  51. cacheExtent: cacheExtent);
  52. @override
  53. void performLayout() {
  54. super.performLayout();
  55. RenderSliver expand;
  56. RenderSliver p = firstChild;
  57. double totalLayoutExtent = 0;
  58. double BehindExtent = 0.0, FrontExtent = 0.0;
  59. while (p != null) {
  60. totalLayoutExtent += p.geometry.scrollExtent;
  61. if (p is _RenderExpanded) {
  62. expand = p;
  63. FrontExtent = totalLayoutExtent;
  64. }
  65. p = childAfter(p);
  66. }
  67. double count = 0;
  68. BehindExtent = totalLayoutExtent - FrontExtent;
  69. if (expand != null && size.height > totalLayoutExtent) {
  70. _attemptLayout(expand, size.height, size.width,
  71. offset.pixels - FrontExtent - (size.height - totalLayoutExtent));
  72. }
  73. }
  74. // _minScrollExtent private in super,no setter method
  75. double _attemptLayout(RenderSliver expandPosition, double mainAxisExtent,
  76. double crossAxisExtent, double correctedOffset) {
  77. assert(!mainAxisExtent.isNaN);
  78. assert(mainAxisExtent >= 0.0);
  79. assert(crossAxisExtent.isFinite);
  80. assert(crossAxisExtent >= 0.0);
  81. assert(correctedOffset.isFinite);
  82. // centerOffset is the offset from the leading edge of the RenderViewport
  83. // to the zero scroll offset (the line between the forward slivers and the
  84. // reverse slivers).
  85. final double centerOffset = mainAxisExtent * anchor - correctedOffset;
  86. final double reverseDirectionRemainingPaintExtent =
  87. centerOffset.clamp(0.0, mainAxisExtent);
  88. final double forwardDirectionRemainingPaintExtent =
  89. (mainAxisExtent - centerOffset).clamp(0.0, mainAxisExtent);
  90. final double fullCacheExtent = mainAxisExtent + 2 * cacheExtent;
  91. final double centerCacheOffset = centerOffset + cacheExtent;
  92. final double reverseDirectionRemainingCacheExtent =
  93. centerCacheOffset.clamp(0.0, fullCacheExtent);
  94. final double forwardDirectionRemainingCacheExtent =
  95. (fullCacheExtent - centerCacheOffset).clamp(0.0, fullCacheExtent);
  96. final RenderSliver leadingNegativeChild = childBefore(center);
  97. // positive scroll offsets
  98. return layoutChildSequence(
  99. child: expandPosition,
  100. scrollOffset: math.max(0.0, -centerOffset),
  101. overlap:
  102. leadingNegativeChild == null ? math.min(0.0, -centerOffset) : 0.0,
  103. layoutOffset: centerOffset >= mainAxisExtent
  104. ? centerOffset
  105. : reverseDirectionRemainingPaintExtent,
  106. remainingPaintExtent: forwardDirectionRemainingPaintExtent,
  107. mainAxisExtent: mainAxisExtent,
  108. crossAxisExtent: crossAxisExtent,
  109. growthDirection: GrowthDirection.forward,
  110. advance: childAfter,
  111. remainingCacheExtent: forwardDirectionRemainingCacheExtent,
  112. cacheOrigin: centerOffset.clamp(-cacheExtent, 0.0),
  113. );
  114. }
  115. }
  116. //tag
  117. class SliverExpanded extends SingleChildRenderObjectWidget {
  118. SliverExpanded() : super(child: Container());
  119. @override
  120. RenderSliver createRenderObject(BuildContext context) {
  121. return _RenderExpanded();
  122. }
  123. }
  124. class _RenderExpanded extends RenderSliver
  125. with RenderObjectWithChildMixin<RenderBox> {
  126. @override
  127. void performLayout() {
  128. geometry = SliverGeometry.zero;
  129. }
  130. }