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
15f6480b
Commit
15f6480b
authored
Mar 11, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2628 from abarth/aspect_ratio
AspectRatio should attempt to fit its height
parents
a237b47c
6a54e122
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
167 additions
and
22 deletions
+167
-22
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+84
-19
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+26
-3
aspect_ratio_test.dart
packages/flutter/test/widget/aspect_ratio_test.dart
+57
-0
No files found.
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
15f6480b
...
...
@@ -345,22 +345,32 @@ class RenderFractionallySizedBox extends RenderProxyBox {
}
}
///
Forces child to layout at
a specific aspect ratio.
///
Attempts to size the child to
a specific aspect ratio.
///
/// The
width of this render object i
s the largest width permited by the layout
/// The
render object first trie
s the largest width permited by the layout
/// constraints. The height of the render object is determined by applying the
/// given aspect ratio to the width, expressed as a ratio of width to height.
/// For example, a 16:9 width:height aspect ratio would have a value of 16.0/9.0.
///
/// For example, given an aspect ratio of 2.0 and layout constraints that
/// require the width to be between 0.0 and 100.0 and the height to be between
/// 0.0 and 100.0, we'll select a width of 100.0 (the biggest allowed) and a
/// height of 50.0 (to match the aspect ratio).
/// For example, a 16:9 width:height aspect ratio would have a value of
/// 16.0/9.0. If the maximum width is infinite, the initial width is determined
/// by applying the aspect ratio to the maximum height.
///
/// Now consider a second example, this time with an aspect ratio of 2.0 and
/// layout constraints that require the width to be between 0.0 and 100.0 and
/// the height to be between 0.0 and 100.0. We'll select a width of 100.0 (the
/// biggest allowed) and a height of 50.0 (to match the aspect ratio).
///
/// In that same situation, if the aspect ratio is 0.5, we'll also select a
/// width of 100.0 (still the biggest allowed) and we'll attempt to use a height
/// of 200.0. Unfortunately, that violates the constraints and we'll end up with
/// a height of 100.0 instead.
/// of 200.0. Unfortunately, that violates the constraints because the child can
/// be at most 100.0 pixels tall. The render object will then take that value
/// and apply the aspect ratio again to obtain a width of 50.0. That width is
/// permitted by the constraints and the child receives a width of 50.0 and a
/// height of 100.0. If the width were not permitted, the render object would
/// continue iterating through the constraints. If the render object does not
/// find a feasible size after consulting each constraint, the render object
/// will eventually select a size for the child that meets the layout
/// constraints but fails to meet the aspect ratio constraints.
class
RenderAspectRatio
extends
RenderProxyBox
{
RenderAspectRatio
({
RenderBox
child
,
...
...
@@ -369,7 +379,7 @@ class RenderAspectRatio extends RenderProxyBox {
assert
(
_aspectRatio
!=
null
);
}
/// The aspect ratio to
use when computing the height from the width
.
/// The aspect ratio to
attempt to use
.
///
/// The aspect ratio is expressed as a ratio of width to height. For example,
/// a 16:9 width:height aspect ratio would have a value of 16.0/9.0.
...
...
@@ -383,28 +393,83 @@ class RenderAspectRatio extends RenderProxyBox {
markNeedsLayout
();
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
constraints
.
minWidth
;
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
constraints
.
maxWidth
;
}
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
return
_applyAspectRatio
(
constraints
).
h
eight
;
return
constraints
.
minH
eight
;
}
double
getMaxIntrinsicHeight
(
BoxConstraints
constraints
)
{
return
_applyAspectRatio
(
constraints
).
h
eight
;
return
constraints
.
maxH
eight
;
}
Size
_applyAspectRatio
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
debugAssertIsNormalized
);
double
width
=
constraints
.
constrainWidth
();
double
height
=
constraints
.
constrainHeight
(
width
/
_aspectRatio
);
return
new
Size
(
width
,
height
);
}
assert
(()
{
if
(!
constraints
.
hasBoundedWidth
&&
!
constraints
.
hasBoundedHeight
)
{
throw
new
RenderingError
(
'
$runtimeType
has unbounded constraints.
\n
'
'This
$runtimeType
was given an aspect ratio of
$aspectRatio
but was given '
'both unbounded width and unbounded height constraints. Because both '
'constraints were unbounded, this render object doesn
\'
t know how much '
'size to consume.'
);
}
return
true
;
});
bool
get
sizedByParent
=>
true
;
if
(
constraints
.
isTight
)
return
constraints
.
smallest
;
void
performResize
()
{
size
=
_applyAspectRatio
(
constraints
);
double
width
=
constraints
.
maxWidth
;
double
height
;
// We default to picking the height based on the width, but if the width
// would be infinite, that's not sensible so we try to infer the height
// from the width.
if
(
width
.
isFinite
)
{
height
=
width
/
_aspectRatio
;
}
else
{
height
=
constraints
.
maxHeight
;
width
=
height
*
_aspectRatio
;
}
// Similar to RenderImage, we iteratively attempt to fit within the given
// constraings while maintaining the given aspect ratio. The order of
// applying the constraints is also biased towards inferring the height
// from the width.
if
(
width
>
constraints
.
maxWidth
)
{
width
=
constraints
.
maxWidth
;
height
=
width
/
_aspectRatio
;
}
if
(
height
>
constraints
.
maxHeight
)
{
height
=
constraints
.
maxHeight
;
width
=
height
*
_aspectRatio
;
}
if
(
width
<
constraints
.
minWidth
)
{
width
=
constraints
.
minWidth
;
height
=
width
/
_aspectRatio
;
}
if
(
height
<
constraints
.
minHeight
)
{
height
=
constraints
.
minHeight
;
width
=
height
*
_aspectRatio
;
}
return
constraints
.
constrain
(
new
Size
(
width
,
height
));
}
void
performLayout
()
{
size
=
_applyAspectRatio
(
constraints
);
if
(
child
!=
null
)
child
.
layout
(
new
BoxConstraints
.
tight
(
size
));
}
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
15f6480b
...
...
@@ -702,16 +702,39 @@ class OffStage extends OneChildRenderObjectWidget {
RenderOffStage
createRenderObject
(
BuildContext
context
)
=>
new
RenderOffStage
();
}
///
Forces child to layout at
a specific aspect ratio.
///
Attempts to size the child to
a specific aspect ratio.
///
/// See [RenderAspectRatio] for details.
/// The widget first tries the largest width permited by the layout
/// constraints. The height of the widget is determined by applying the
/// given aspect ratio to the width, expressed as a ratio of width to height.
///
/// For example, a 16:9 width:height aspect ratio would have a value of
/// 16.0/9.0. If the maximum width is infinite, the initial width is determined
/// by applying the aspect ratio to the maximum height.
///
/// Now consider a second example, this time with an aspect ratio of 2.0 and
/// layout constraints that require the width to be between 0.0 and 100.0 and
/// the height to be between 0.0 and 100.0. We'll select a width of 100.0 (the
/// biggest allowed) and a height of 50.0 (to match the aspect ratio).
///
/// In that same situation, if the aspect ratio is 0.5, we'll also select a
/// width of 100.0 (still the biggest allowed) and we'll attempt to use a height
/// of 200.0. Unfortunately, that violates the constraints because the child can
/// be at most 100.0 pixels tall. The widget will then take that value
/// and apply the aspect ratio again to obtain a width of 50.0. That width is
/// permitted by the constraints and the child receives a width of 50.0 and a
/// height of 100.0. If the width were not permitted, the widget would
/// continue iterating through the constraints. If the widget does not
/// find a feasible size after consulting each constraint, the widget
/// will eventually select a size for the child that meets the layout
/// constraints but fails to meet the aspect ratio constraints.
class
AspectRatio
extends
OneChildRenderObjectWidget
{
AspectRatio
({
Key
key
,
this
.
aspectRatio
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
aspectRatio
!=
null
);
}
/// The aspect ratio to
use when computing the height from the width
.
/// The aspect ratio to
attempt to use
.
///
/// The aspect ratio is expressed as a ratio of width to height. For example,
/// a 16:9 width:height aspect ratio would have a value of 16.0/9.0.
...
...
packages/flutter/test/widget/aspect_ratio_test.dart
0 → 100644
View file @
15f6480b
// 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_test/flutter_test.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:test/test.dart'
;
Size
_getSize
(
WidgetTester
tester
,
BoxConstraints
constraints
,
double
aspectRatio
)
{
Key
childKey
=
new
UniqueKey
();
tester
.
pumpWidget
(
new
Center
(
child:
new
ConstrainedBox
(
constraints:
constraints
,
child:
new
AspectRatio
(
aspectRatio:
aspectRatio
,
child:
new
Container
(
key:
childKey
)
)
)
)
);
RenderBox
box
=
tester
.
findElementByKey
(
childKey
).
renderObject
;
return
box
.
size
;
}
void
main
(
)
{
test
(
'Aspect ratio control test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
expect
(
_getSize
(
tester
,
new
BoxConstraints
.
loose
(
new
Size
(
500.0
,
500.0
)),
2.0
),
equals
(
new
Size
(
500.0
,
250.0
)));
expect
(
_getSize
(
tester
,
new
BoxConstraints
.
loose
(
new
Size
(
500.0
,
500.0
)),
0.5
),
equals
(
new
Size
(
250.0
,
500.0
)));
});
});
test
(
'Aspect ratio infinite width'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
Key
childKey
=
new
UniqueKey
();
tester
.
pumpWidget
(
new
Center
(
child:
new
Viewport
(
scrollDirection:
Axis
.
horizontal
,
child:
new
AspectRatio
(
aspectRatio:
2.0
,
child:
new
Container
(
key:
childKey
)
)
)
)
);
RenderBox
box
=
tester
.
findElementByKey
(
childKey
).
renderObject
;
expect
(
box
.
size
,
equals
(
new
Size
(
1200.0
,
600.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