Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
6e9bbca4
Commit
6e9bbca4
authored
Aug 18, 2016
by
Dragoș Tiselice
Committed by
GitHub
Aug 18, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added AnimatedSize. (#5260)
Added a widget that implicitly animates the size of it child.
parent
f28cf641
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
378 additions
and
3 deletions
+378
-3
rendering.dart
packages/flutter/lib/rendering.dart
+1
-0
animated_size.dart
packages/flutter/lib/src/rendering/animated_size.dart
+139
-0
animated_size.dart
packages/flutter/lib/src/widgets/animated_size.dart
+62
-0
implicit_animations.dart
packages/flutter/lib/src/widgets/implicit_animations.dart
+3
-3
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
animated_size_test.dart
packages/flutter/test/widget/animated_size_test.dart
+172
-0
No files found.
packages/flutter/lib/rendering.dart
View file @
6e9bbca4
...
...
@@ -22,6 +22,7 @@
/// initialized with those features.
library
rendering
;
export
'src/rendering/animated_size.dart'
;
export
'src/rendering/auto_layout.dart'
;
export
'src/rendering/binding.dart'
;
export
'src/rendering/block.dart'
;
...
...
packages/flutter/lib/src/rendering/animated_size.dart
0 → 100644
View file @
6e9bbca4
// Copyright 2016 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.
import
'package:flutter/animation.dart'
;
import
'package:meta/meta.dart'
;
import
'box.dart'
;
import
'object.dart'
;
import
'shifted_box.dart'
;
/// A render object that animates its size to its child's size over a given
/// [duration] and with a given [curve]. In case the child's size is animating
/// as opposed to abruptly changing size, the parent behaves like a normal
/// container.
///
/// In case the child overflows the current animated size of the parent, it gets
/// clipped automatically.
class
RenderAnimatedSize
extends
RenderAligningShiftedBox
{
/// Creates a render object that animates its size to match its child.
/// The [duration] and [curve] arguments define the animation. The [alignment]
/// argument is used to align the child in the case where the parent is not
/// (yet) the same size as the child.
///
/// The arguments [duration], [curve], and [alignment] should not be null.
RenderAnimatedSize
({
Curve
curve:
Curves
.
linear
,
RenderBox
child
,
FractionalOffset
alignment:
FractionalOffset
.
center
,
@required
Duration
duration
})
:
super
(
child:
child
,
alignment:
alignment
)
{
assert
(
duration
!=
null
);
assert
(
curve
!=
null
);
_controller
=
new
AnimationController
(
duration:
duration
)..
addListener
(()
{
if
(
_controller
.
value
!=
_lastValue
)
markNeedsLayout
();
});
_animation
=
new
CurvedAnimation
(
parent:
_controller
,
curve:
curve
);
}
AnimationController
_controller
;
CurvedAnimation
_animation
;
SizeTween
_sizeTween
=
new
SizeTween
();
bool
_didChangeTargetSizeLastFrame
=
false
;
bool
_hasVisualOverflow
;
double
_lastValue
;
/// The duration of the animation.
Duration
get
duration
=>
_controller
.
duration
;
set
duration
(
Duration
value
)
{
assert
(
value
!=
null
);
if
(
value
==
_controller
.
duration
)
return
;
_controller
.
duration
=
value
;
}
/// The curve of the animation.
Curve
get
curve
=>
_animation
.
curve
;
set
curve
(
Curve
value
)
{
assert
(
value
!=
null
);
if
(
value
==
_animation
.
curve
)
return
;
_animation
.
curve
=
value
;
}
@override
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
if
(
_animatedSize
!=
_sizeTween
.
end
&&
!
_controller
.
isAnimating
)
_controller
.
forward
();
}
@override
void
detach
()
{
_controller
.
stop
();
super
.
detach
();
}
Size
get
_animatedSize
{
return
_sizeTween
.
evaluate
(
_animation
);
}
@override
void
performLayout
()
{
_lastValue
=
_controller
.
value
;
_hasVisualOverflow
=
false
;
if
(
child
==
null
)
{
size
=
_sizeTween
.
begin
=
_sizeTween
.
end
=
constraints
.
smallest
;
return
;
}
child
.
layout
(
constraints
,
parentUsesSize:
true
);
if
(
_sizeTween
.
end
!=
child
.
size
)
{
_sizeTween
.
begin
=
_animatedSize
??
child
.
size
;
_sizeTween
.
end
=
child
.
size
;
if
(
_didChangeTargetSizeLastFrame
)
{
size
=
child
.
size
;
_controller
.
stop
();
}
else
{
// Don't register first change (i.e. when _targetSize == _sourceSize)
// as a last-frame change.
if
(
_sizeTween
.
end
!=
_sizeTween
.
begin
)
_didChangeTargetSizeLastFrame
=
true
;
_lastValue
=
0.0
;
_controller
.
forward
(
from:
0.0
);
size
=
constraints
.
constrain
(
_animatedSize
);
}
}
else
{
_didChangeTargetSizeLastFrame
=
false
;
size
=
constraints
.
constrain
(
_animatedSize
);
}
alignChild
();
if
(
size
.
width
<
_sizeTween
.
end
.
width
||
size
.
height
<
_sizeTween
.
end
.
height
)
_hasVisualOverflow
=
true
;
}
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
&&
_hasVisualOverflow
)
{
final
Rect
rect
=
Point
.
origin
&
size
;
context
.
pushClipRect
(
needsCompositing
,
offset
,
rect
,
super
.
paint
);
}
else
{
super
.
paint
(
context
,
offset
);
}
}
}
packages/flutter/lib/src/widgets/animated_size.dart
0 → 100644
View file @
6e9bbca4
// Copyright 2016 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.
import
'package:flutter/rendering.dart'
;
import
'package:meta/meta.dart'
;
import
'basic.dart'
;
import
'framework.dart'
;
/// Animated widget that automatically transitions its size over a given
/// duration whenever the given child's size changes.
class
AnimatedSize
extends
SingleChildRenderObjectWidget
{
/// Creates a widget that animates its size to match that of its child.
///
/// The [curve] and [duration] arguments must not be null.
AnimatedSize
({
Key
key
,
Widget
child
,
this
.
alignment
:
FractionalOffset
.
center
,
this
.
curve
:
Curves
.
linear
,
@required
this
.
duration
})
:
super
(
key:
key
,
child:
child
);
/// The alignment of the child within the parent when the parent is not yet
/// the same size as the child.
///
/// The x and y values of the alignment control the horizontal and vertical
/// alignment, respectively. An x value of 0.0 means that the left edge of
/// the child is aligned with the left edge of the parent whereas an x value
/// of 1.0 means that the right edge of the child is aligned with the right
/// edge of the parent. Other values interpolate (and extrapolate) linearly.
/// For example, a value of 0.5 means that the center of the child is aligned
/// with the center of the parent.
final
FractionalOffset
alignment
;
/// The animation curve when transitioning this widget's size to match the
/// child's size.
final
Curve
curve
;
/// The duration when transitioning this widget's size to match the child's
/// size.
final
Duration
duration
;
@override
RenderAnimatedSize
createRenderObject
(
BuildContext
context
)
{
return
new
RenderAnimatedSize
(
alignment:
alignment
,
duration:
duration
,
curve:
curve
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
RenderAnimatedSize
renderObject
)
{
renderObject
..
alignment
=
alignment
..
duration
=
duration
..
curve
=
curve
;
}
}
packages/flutter/lib/src/widgets/implicit_animations.dart
View file @
6e9bbca4
...
...
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:meta/meta.dart'
;
import
'package:vector_math/vector_math_64.dart'
;
import
'basic.dart'
;
import
'container.dart'
;
import
'framework.dart'
;
import
'package:meta/meta.dart'
;
import
'package:vector_math/vector_math_64.dart'
;
/// An interpolation between two [BoxConstraint]s.
class
BoxConstraintsTween
extends
Tween
<
BoxConstraints
>
{
/// Creates a box constraints tween.
...
...
packages/flutter/lib/widgets.dart
View file @
6e9bbca4
...
...
@@ -8,6 +8,7 @@
/// To use, import `package:flutter/widgets.dart`.
library
widgets
;
export
'src/widgets/animated_size.dart'
;
export
'src/widgets/app.dart'
;
export
'src/widgets/auto_layout.dart'
;
export
'src/widgets/banner.dart'
;
...
...
packages/flutter/test/widget/animated_size_test.dart
0 → 100644
View file @
6e9bbca4
// Copyright 2016 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.
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
class
TestPaintingContext
implements
PaintingContext
{
final
List
<
Invocation
>
invocations
=
<
Invocation
>[];
@override
void
noSuchMethod
(
Invocation
invocation
)
{
invocations
.
add
(
invocation
);
}
}
void
main
(
)
{
testWidgets
(
'AnimatedSize test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Center
(
child:
new
AnimatedSize
(
duration:
const
Duration
(
milliseconds:
200
),
child:
new
SizedBox
(
width:
100.0
,
height:
100.0
)
)
)
);
RenderBox
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
100.0
));
expect
(
box
.
size
.
height
,
equals
(
100.0
));
await
tester
.
pumpWidget
(
new
Center
(
child:
new
AnimatedSize
(
duration:
new
Duration
(
milliseconds:
200
),
child:
new
SizedBox
(
width:
200.0
,
height:
200.0
)
)
)
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
150.0
));
expect
(
box
.
size
.
height
,
equals
(
150.0
));
TestPaintingContext
context
=
new
TestPaintingContext
();
box
.
paint
(
context
,
Offset
.
zero
);
expect
(
context
.
invocations
.
first
.
memberName
,
equals
(
#pushClipRect
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
200.0
));
expect
(
box
.
size
.
height
,
equals
(
200.0
));
await
tester
.
pumpWidget
(
new
Center
(
child:
new
AnimatedSize
(
duration:
new
Duration
(
milliseconds:
200
),
child:
new
SizedBox
(
width:
100.0
,
height:
100.0
)
)
)
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
150.0
));
expect
(
box
.
size
.
height
,
equals
(
150.0
));
context
=
new
TestPaintingContext
();
box
.
paint
(
context
,
Offset
.
zero
);
expect
(
context
.
invocations
.
first
.
memberName
,
equals
(
#paintChild
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
100.0
));
expect
(
box
.
size
.
height
,
equals
(
100.0
));
});
testWidgets
(
'AnimatedSize constrained test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Center
(
child:
new
SizedBox
(
width:
100.0
,
height:
100.0
,
child:
new
AnimatedSize
(
duration:
const
Duration
(
milliseconds:
200
),
child:
new
SizedBox
(
width:
100.0
,
height:
100.0
)
)
)
)
);
RenderBox
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
100.0
));
expect
(
box
.
size
.
height
,
equals
(
100.0
));
await
tester
.
pumpWidget
(
new
Center
(
child:
new
SizedBox
(
width:
100.0
,
height:
100.0
,
child:
new
AnimatedSize
(
duration:
const
Duration
(
milliseconds:
200
),
child:
new
SizedBox
(
width:
200.0
,
height:
200.0
)
)
)
)
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
100.0
));
expect
(
box
.
size
.
height
,
equals
(
100.0
));
});
testWidgets
(
'AnimatedSize with AnimatedContainer'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Center
(
child:
new
AnimatedSize
(
duration:
const
Duration
(
milliseconds:
200
),
child:
new
AnimatedContainer
(
duration:
const
Duration
(
milliseconds:
100
),
width:
100.0
,
height:
100.0
)
)
)
);
RenderBox
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
100.0
));
expect
(
box
.
size
.
height
,
equals
(
100.0
));
await
tester
.
pumpWidget
(
new
Center
(
child:
new
AnimatedSize
(
duration:
const
Duration
(
milliseconds:
200
),
child:
new
AnimatedContainer
(
duration:
const
Duration
(
milliseconds:
100
),
width:
200.0
,
height:
200.0
)
)
)
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
1
));
// register change
await
tester
.
pump
(
const
Duration
(
milliseconds:
49
));
expect
(
box
.
size
.
width
,
equals
(
150.0
));
expect
(
box
.
size
.
height
,
equals
(
150.0
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
box
=
tester
.
renderObject
(
find
.
byType
(
AnimatedSize
));
expect
(
box
.
size
.
width
,
equals
(
200.0
));
expect
(
box
.
size
.
height
,
equals
(
200.0
));
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment