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
95803ebb
Commit
95803ebb
authored
Oct 20, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1690 from abarth/transition_container
Adds EnterExitTransition widget
parents
a6c10185
d54d35d3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
381 additions
and
2 deletions
+381
-2
smooth_resize.dart
examples/widgets/smooth_resize.dart
+115
-0
overflow.dart
packages/flutter/lib/src/rendering/overflow.dart
+61
-0
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+6
-2
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+13
-0
enter_exit_transition.dart
packages/flutter/lib/src/widgets/enter_exit_transition.dart
+185
-0
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
No files found.
examples/widgets/smooth_resize.dart
0 → 100644
View file @
95803ebb
// 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.
import
'package:flutter/animation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
final
List
<
Map
<
int
,
Color
>>
_kColors
=
[
Colors
.
amber
,
Colors
.
yellow
,
Colors
.
blue
,
Colors
.
purple
,
Colors
.
indigo
,
Colors
.
deepOrange
,
];
class
SmoothBlock
extends
StatefulComponent
{
SmoothBlock
({
this
.
color
});
final
Map
<
int
,
Color
>
color
;
SmoothBlockState
createState
()
=>
new
SmoothBlockState
();
}
class
CardTransition
extends
StatelessComponent
{
CardTransition
({
this
.
child
,
this
.
performance
,
this
.
x
,
this
.
opacity
,
this
.
scale
});
final
Widget
child
;
final
Performance
performance
;
final
AnimatedValue
<
double
>
x
;
final
AnimatedValue
<
double
>
opacity
;
final
AnimatedValue
<
double
>
scale
;
Widget
build
(
BuildContext
context
)
{
return
new
BuilderTransition
(
performance:
performance
,
variables:
[
x
,
opacity
,
scale
],
builder:
(
BuildContext
context
)
{
Matrix4
transform
=
new
Matrix4
.
identity
()
..
translate
(
x
.
value
)
..
scale
(
scale
.
value
,
scale
.
value
);
return
new
Opacity
(
opacity:
opacity
.
value
,
child:
new
Transform
(
transform:
transform
,
child:
child
)
);
}
);
}
}
class
SmoothBlockState
extends
State
<
SmoothBlock
>
{
double
_height
=
100.0
;
Widget
_handleEnter
(
PerformanceView
performance
,
Widget
child
)
{
return
new
CardTransition
(
x:
new
AnimatedValue
<
double
>(-
200.0
,
end:
0.0
,
curve:
Curves
.
ease
),
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
Curves
.
ease
),
scale:
new
AnimatedValue
<
double
>(
0.8
,
end:
1.0
,
curve:
Curves
.
ease
),
performance:
performance
,
child:
child
);
}
Widget
_handleExit
(
PerformanceView
performance
,
Widget
child
)
{
return
new
CardTransition
(
x:
new
AnimatedValue
<
double
>(
0.0
,
end:
200.0
,
curve:
Curves
.
ease
),
opacity:
new
AnimatedValue
<
double
>(
1.0
,
end:
0.0
,
curve:
Curves
.
ease
),
scale:
new
AnimatedValue
<
double
>(
1.0
,
end:
0.8
,
curve:
Curves
.
ease
),
performance:
performance
,
child:
child
);
}
Widget
build
(
BuildContext
context
)
{
return
new
GestureDetector
(
onTap:
()
{
setState
(()
{
_height
=
_height
==
100.0
?
200.0
:
100.0
;
});
},
child:
new
EnterExitTransition
(
duration:
const
Duration
(
milliseconds:
1500
),
onEnter:
_handleEnter
,
onExit:
_handleExit
,
child:
new
Container
(
key:
new
ValueKey
(
_height
),
height:
_height
,
decoration:
new
BoxDecoration
(
backgroundColor:
config
.
color
[
_height
.
floor
()
*
4
])
)
)
);
}
}
class
SmoothResizeDemo
extends
StatelessComponent
{
Widget
build
(
BuildContext
context
)
{
return
new
Block
(
_kColors
.
map
((
Map
<
int
,
Color
>
color
)
=>
new
SmoothBlock
(
color:
color
)).
toList
());
}
}
void
main
(
)
{
runApp
(
new
SmoothResizeDemo
());
}
packages/flutter/lib/src/rendering/overflow.dart
View file @
95803ebb
...
@@ -146,6 +146,67 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render
...
@@ -146,6 +146,67 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render
}
}
}
}
/// A render box that's a specific size but passes its original constraints through to its child, which will probably overflow
class
RenderSizedOverflowBox
extends
RenderBox
with
RenderObjectWithChildMixin
<
RenderBox
>
{
RenderSizedOverflowBox
({
RenderBox
child
,
Size
requestedSize
})
:
_requestedSize
=
requestedSize
{
assert
(
requestedSize
!=
null
);
this
.
child
=
child
;
}
/// The size this render box should attempt to be.
Size
get
requestedSize
=>
_requestedSize
;
Size
_requestedSize
;
void
set
requestedSize
(
Size
value
)
{
assert
(
value
!=
null
);
if
(
_requestedSize
==
value
)
return
;
_requestedSize
=
value
;
markNeedsLayout
();
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
constraints
.
constrainWidth
(
_requestedSize
.
width
);
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
constraints
.
constrainWidth
(
_requestedSize
.
width
);
}
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
return
constraints
.
constrainWidth
(
_requestedSize
.
height
);
}
double
getMaxIntrinsicHeight
(
BoxConstraints
constraints
)
{
return
constraints
.
constrainWidth
(
_requestedSize
.
height
);
}
double
computeDistanceToActualBaseline
(
TextBaseline
baseline
)
{
if
(
child
!=
null
)
return
child
.
getDistanceToActualBaseline
(
baseline
);
return
super
.
computeDistanceToActualBaseline
(
baseline
);
}
void
performLayout
()
{
size
=
constraints
.
constrain
(
_requestedSize
);
if
(
child
!=
null
)
child
.
layout
(
constraints
);
}
void
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
if
(
child
!=
null
)
child
.
hitTest
(
result
,
position:
position
);
else
super
.
hitTestChildren
(
result
,
position:
position
);
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
context
.
paintChild
(
child
,
offset
.
toPoint
());
}
}
/// Lays the child out as if it was in the tree, but without painting anything,
/// Lays the child out as if it was in the tree, but without painting anything,
/// without making the child available for hit testing, and without taking any
/// without making the child available for hit testing, and without taking any
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
95803ebb
...
@@ -861,8 +861,12 @@ class RenderSizeObserver extends RenderProxyBox {
...
@@ -861,8 +861,12 @@ class RenderSizeObserver extends RenderProxyBox {
void
performLayout
()
{
void
performLayout
()
{
Size
oldSize
=
hasSize
?
size
:
null
;
Size
oldSize
=
hasSize
?
size
:
null
;
super
.
performLayout
();
super
.
performLayout
();
if
(
oldSize
!=
size
)
if
(
oldSize
!=
size
)
{
onSizeChanged
(
size
);
// We make a copy of the Size object here because if we leak a _DebugSize
// object out of the render tree, we can get confused later if it comes
// back and gets set as the size property of a RenderBox.
onSizeChanged
(
new
Size
(
size
.
width
,
size
.
height
));
}
}
}
}
}
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
95803ebb
...
@@ -346,6 +346,19 @@ class OverflowBox extends OneChildRenderObjectWidget {
...
@@ -346,6 +346,19 @@ class OverflowBox extends OneChildRenderObjectWidget {
}
}
}
}
class
SizedOverflowBox
extends
OneChildRenderObjectWidget
{
SizedOverflowBox
({
Key
key
,
this
.
size
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
final
Size
size
;
RenderSizedOverflowBox
createRenderObject
()
=>
new
RenderSizedOverflowBox
(
requestedSize:
size
);
void
updateRenderObject
(
RenderSizedOverflowBox
renderObject
,
SizedOverflowBox
oldWidget
)
{
renderObject
.
requestedSize
=
size
;
}
}
class
OffStage
extends
OneChildRenderObjectWidget
{
class
OffStage
extends
OneChildRenderObjectWidget
{
OffStage
({
Key
key
,
Widget
child
})
OffStage
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
:
super
(
key:
key
,
child:
child
);
...
...
packages/flutter/lib/src/widgets/enter_exit_transition.dart
0 → 100644
View file @
95803ebb
// 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.
import
'dart:async'
;
import
'package:flutter/animation.dart'
;
import
'basic.dart'
;
import
'framework.dart'
;
class
SmoothlyResizingOverflowBox
extends
StatefulComponent
{
SmoothlyResizingOverflowBox
({
Key
key
,
this
.
child
,
this
.
size
,
this
.
duration
,
this
.
curve
:
Curves
.
linear
})
:
super
(
key:
key
)
{
assert
(
duration
!=
null
);
assert
(
curve
!=
null
);
}
final
Widget
child
;
final
Size
size
;
final
Duration
duration
;
final
Curve
curve
;
_SmoothlyResizingOverflowBoxState
createState
()
=>
new
_SmoothlyResizingOverflowBoxState
();
}
class
_SmoothlyResizingOverflowBoxState
extends
State
<
SmoothlyResizingOverflowBox
>
{
ValuePerformance
<
Size
>
_size
;
void
initState
()
{
super
.
initState
();
_size
=
new
ValuePerformance
(
variable:
new
AnimatedSizeValue
(
config
.
size
,
curve:
config
.
curve
),
duration:
config
.
duration
)..
addListener
(()
{
setState
(()
{});
});
}
void
didUpdateConfig
(
SmoothlyResizingOverflowBox
oldConfig
)
{
_size
.
duration
=
config
.
duration
;
_size
.
variable
.
curve
=
config
.
curve
;
if
(
config
.
size
!=
oldConfig
.
size
)
{
AnimatedSizeValue
variable
=
_size
.
variable
;
variable
.
begin
=
variable
.
value
;
variable
.
end
=
config
.
size
;
_size
.
progress
=
0.0
;
_size
.
play
();
}
}
void
dispose
()
{
_size
.
stop
();
super
.
dispose
();
}
Widget
build
(
BuildContext
context
)
{
return
new
SizedOverflowBox
(
size:
_size
.
value
,
child:
config
.
child
);
}
}
class
_Entry
{
_Entry
({
this
.
child
,
this
.
enterPerformance
,
this
.
enterTransition
});
final
Widget
child
;
final
Performance
enterPerformance
;
final
Widget
enterTransition
;
Size
childSize
=
Size
.
zero
;
Performance
exitPerformance
;
Widget
exitTransition
;
Widget
get
currentTransition
=>
exitTransition
??
enterTransition
;
void
dispose
()
{
enterPerformance
?.
stop
();
exitPerformance
?.
stop
();
}
}
typedef
Widget
TransitionBuilderCallback
(
PerformanceView
performance
,
Widget
child
);
class
EnterExitTransition
extends
StatefulComponent
{
EnterExitTransition
({
Key
key
,
this
.
child
,
this
.
duration
,
this
.
curve
:
Curves
.
linear
,
this
.
onEnter
,
this
.
onExit
})
:
super
(
key:
key
)
{
assert
(
child
!=
null
);
assert
(
duration
!=
null
);
assert
(
curve
!=
null
);
assert
(
onEnter
!=
null
);
assert
(
onExit
!=
null
);
}
final
Widget
child
;
final
Duration
duration
;
final
Curve
curve
;
final
TransitionBuilderCallback
onEnter
;
final
TransitionBuilderCallback
onExit
;
_EnterExitTransitionState
createState
()
=>
new
_EnterExitTransitionState
();
}
class
_EnterExitTransitionState
extends
State
<
EnterExitTransition
>
{
final
List
<
_Entry
>
_entries
=
new
List
<
_Entry
>();
void
initState
()
{
super
.
initState
();
_entries
.
add
(
_createEnterTransition
());
}
_Entry
_createEnterTransition
()
{
Performance
enterPerformance
=
new
Performance
(
duration:
config
.
duration
)..
play
();
return
new
_Entry
(
child:
config
.
child
,
enterPerformance:
enterPerformance
,
enterTransition:
config
.
onEnter
(
enterPerformance
,
new
KeyedSubtree
(
key:
new
GlobalKey
(),
child:
config
.
child
))
);
}
Future
_createExitTransition
(
_Entry
entry
)
async
{
Performance
exitPerformance
=
new
Performance
(
duration:
config
.
duration
);
entry
..
exitPerformance
=
exitPerformance
..
exitTransition
=
config
.
onExit
(
exitPerformance
,
entry
.
enterTransition
);
await
exitPerformance
.
play
();
if
(!
mounted
)
return
;
setState
(()
{
_entries
.
remove
(
entry
);
});
}
void
didUpdateConfig
(
EnterExitTransition
oldConfig
)
{
if
(
config
.
child
.
key
!=
oldConfig
.
child
.
key
)
{
_createExitTransition
(
_entries
.
last
);
_entries
.
add
(
_createEnterTransition
());
}
}
void
dispose
()
{
for
(
_Entry
entry
in
new
List
<
_Entry
>.
from
(
_entries
))
entry
.
dispose
();
super
.
dispose
();
}
Widget
build
(
BuildContext
context
)
{
return
new
SmoothlyResizingOverflowBox
(
size:
_entries
.
last
.
childSize
,
duration:
config
.
duration
,
curve:
config
.
curve
,
child:
new
Stack
(
_entries
.
map
((
_Entry
entry
)
{
return
new
SizeObserver
(
key:
new
ObjectKey
(
entry
),
onSizeChanged:
(
Size
newSize
)
{
setState
(()
{
entry
.
childSize
=
newSize
;
});
},
child:
entry
.
currentTransition
);
}).
toList
())
);
}
}
packages/flutter/lib/widgets.dart
View file @
95803ebb
...
@@ -11,6 +11,7 @@ export 'src/widgets/binding.dart';
...
@@ -11,6 +11,7 @@ export 'src/widgets/binding.dart';
export
'src/widgets/dismissable.dart'
;
export
'src/widgets/dismissable.dart'
;
export
'src/widgets/drag_target.dart'
;
export
'src/widgets/drag_target.dart'
;
export
'src/widgets/editable_text.dart'
;
export
'src/widgets/editable_text.dart'
;
export
'src/widgets/enter_exit_transition.dart'
;
export
'src/widgets/focus.dart'
;
export
'src/widgets/focus.dart'
;
export
'src/widgets/framework.dart'
;
export
'src/widgets/framework.dart'
;
export
'src/widgets/gesture_detector.dart'
;
export
'src/widgets/gesture_detector.dart'
;
...
...
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