void _initGap(MaterialGap gap) { AnimationController controller = new AnimationController( duration: ThemeUtils.kThemeAnimationDuration, vsync: this); CurvedAnimation startAnimation = new CurvedAnimation( parent: controller, curve: Curves.fastOutSlowIn); CurvedAnimation endAnimation = new CurvedAnimation( parent: controller, curve: Curves.fastOutSlowIn); CurvedAnimation gapAnimation = new CurvedAnimation( parent: controller, curve: Curves.fastOutSlowIn); controller.addListener(this._handleTick); this._animationTuples[gap.key] = new _AnimationTuple( controller: controller, startAnimation: startAnimation, endAnimation: endAnimation, gapAnimation: gapAnimation); }
float _getGapSize(int index) { MaterialGap gap = (MaterialGap)this._children[index]; return(MathUtils.lerpFloat(this._animationTuples[gap.key].gapStart, gap.size, this._animationTuples[gap.key].gapAnimation.value)); }
public override void didUpdateWidget(StatefulWidget oldWidget) { base.didUpdateWidget(oldWidget); MergeableMaterial _oldWidget = (MergeableMaterial)oldWidget; HashSet <LocalKey> oldKeys = new HashSet <LocalKey>(); foreach (MergeableMaterialItem child in _oldWidget.children) { oldKeys.Add(child.key); } HashSet <LocalKey> newKeys = new HashSet <LocalKey>(); foreach (MergeableMaterialItem child in this.widget.children) { newKeys.Add(child.key); } HashSet <LocalKey> newOnly = new HashSet <LocalKey>(); foreach (var key in newKeys) { if (!oldKeys.Contains(key)) { newOnly.Add(key); } } HashSet <LocalKey> oldOnly = new HashSet <LocalKey>(); foreach (var key in oldKeys) { if (!newKeys.Contains(key)) { oldOnly.Add(key); } } List <MergeableMaterialItem> newChildren = this.widget.children; int i = 0; int j = 0; D.assert(this._debugGapsAreValid(newChildren)); this._removeEmptyGaps(); while (i < newChildren.Count && j < this._children.Count) { if (newOnly.Contains(newChildren[i].key) || oldOnly.Contains(this._children[j].key)) { int startNew = i; int startOld = j; while (newOnly.Contains(newChildren[i].key)) { i++; } while (oldOnly.Contains(this._children[j].key) || this._isClosingGap(j)) { j++; } int newLength = i - startNew; int oldLength = j - startOld; if (newLength > 0) { if (oldLength > 1 || oldLength == 1 && this._children[startOld] is MaterialSlice) { if (newLength == 1 && newChildren[startNew] is MaterialGap) { float gapSizeSum = 0.0f; while (startOld < j) { if (this._children[startOld] is MaterialGap) { MaterialGap gap = (MaterialGap)this._children[startOld]; gapSizeSum += gap.size; } this._removeChild(startOld); j--; } this._insertChild(startOld, newChildren[startNew]); this._animationTuples[newChildren[startNew].key].gapStart = gapSizeSum; this._animationTuples[newChildren[startNew].key].controller.forward(); j++; } else { for (int k = 0; k < oldLength; k++) { this._removeChild(startOld); } for (int k = 0; k < newLength; k++) { this._insertChild(startOld + k, newChildren[startNew + k]); } j += (newLength - oldLength); } } else if (oldLength == 1) { if (newLength == 1 && newChildren[startNew] is MaterialGap && this._children[startOld].key == newChildren[startNew].key) { this._animationTuples[newChildren[startNew].key].controller.forward(); } else { float gapSize = this._getGapSize(startOld); this._removeChild(startOld); for (int k = 0; k < newLength; k++) { this._insertChild(startOld + k, newChildren[startNew + k]); } j += (newLength - 1); float gapSizeSum = 0.0f; for (int k = startNew; k < i; k++) { if (newChildren[k] is MaterialGap) { MaterialGap gap = (MaterialGap)newChildren[k]; gapSizeSum += gap.size; } } for (int k = startNew; k < i; k++) { if (newChildren[k] is MaterialGap) { MaterialGap gap = (MaterialGap)newChildren[k]; this._animationTuples[gap.key].gapStart = gapSize * gap.size / gapSizeSum; this._animationTuples[gap.key].controller.setValue(0.0f); this._animationTuples[gap.key].controller.forward(); } } } } else { for (int k = 0; k < newLength; k++) { this._insertChild(startOld + k, newChildren[startNew + k]); if (newChildren[startNew + k] is MaterialGap) { MaterialGap gap = (MaterialGap)newChildren[startNew + k]; this._animationTuples[gap.key].controller.forward(); } } j += newLength; } } else { if (oldLength > 1 || oldLength == 1 && this._children[startOld] is MaterialSlice) { float gapSizeSum = 0.0f; while (startOld < j) { if (this._children[startOld] is MaterialGap) { MaterialGap gap = (MaterialGap)this._children[startOld]; gapSizeSum += gap.size; } this._removeChild(startOld); j--; } if (gapSizeSum != 0.0) { MaterialGap gap = new MaterialGap(key: new UniqueKey(), size: gapSizeSum); this._insertChild(startOld, gap); this._animationTuples[gap.key].gapStart = 0.0f; this._animationTuples[gap.key].controller.setValue(1.0f); this._animationTuples[gap.key].controller.reverse(); j++; } } else if (oldLength == 1) { MaterialGap gap = (MaterialGap)this._children[startOld]; this._animationTuples[gap.key].gapStart = 0.0f; this._animationTuples[gap.key].controller.reverse(); } } } else { if ((this._children[j] is MaterialGap) == (newChildren[i] is MaterialGap)) { this._children[j] = newChildren[i]; i++; j++; } else { D.assert(this._children[j] is MaterialGap); j++; } } } while (j < this._children.Count) { this._removeChild(j); } while (i < newChildren.Count) { this._insertChild(j, newChildren[i]); i++; j++; } }