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
eb69f594
Unverified
Commit
eb69f594
authored
Jul 19, 2018
by
Jonah Williams
Committed by
GitHub
Jul 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow material button to grow as wide as its constraints allow (#19416)
parent
73960e75
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
119 additions
and
49 deletions
+119
-49
button.dart
packages/flutter/lib/src/material/button.dart
+77
-32
raw_material_button_test.dart
packages/flutter/test/material/raw_material_button_test.dart
+42
-17
No files found.
packages/flutter/lib/src/material/button.dart
View file @
eb69f594
...
...
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
...
...
@@ -166,7 +168,7 @@ class _RawMaterialButtonState extends State<RawMaterialButton> {
?
(
_highlight
?
widget
.
highlightElevation
:
widget
.
elevation
)
:
widget
.
disabledElevation
;
Widget
result
=
new
ConstrainedBox
(
final
Widget
result
=
new
ConstrainedBox
(
constraints:
widget
.
constraints
,
child:
new
Material
(
elevation:
elevation
,
...
...
@@ -194,29 +196,24 @@ class _RawMaterialButtonState extends State<RawMaterialButton> {
),
),
);
BoxConstraints
constraints
;
Size
minSize
;
switch
(
widget
.
materialTapTargetSize
)
{
case
MaterialTapTargetSize
.
padded
:
constraints
=
const
BoxConstraints
(
minWidth:
48.0
,
minHeight:
48.0
);
minSize
=
const
Size
(
48.0
,
48.0
);
break
;
case
MaterialTapTargetSize
.
shrinkWrap
:
constraints
=
const
BoxConstraints
()
;
minSize
=
Size
.
zero
;
break
;
}
result
=
new
_ButtonRedirectingHitDetectionWidget
(
constraints:
constraints
,
child:
new
Center
(
child:
result
,
widthFactor:
1.0
,
heightFactor:
1.0
,
),
);
return
new
Semantics
(
container:
true
,
button:
true
,
enabled:
widget
.
enabled
,
child:
result
,
child:
new
_InputPadding
(
minSize:
minSize
,
child:
result
,
),
);
}
}
...
...
@@ -446,40 +443,88 @@ class MaterialButton extends StatelessWidget {
}
}
///
Redirects the position passed to [RenderBox.hitTest] to the center of the
///
widget if the child hit test would have failed otherwise.
///
///
The primary purpose of this widget is to allow padding around [Material] widgets
///
to trigger the child ink feature without increasing the size of the material
.
class
_
ButtonRedirectingHitDetectionWidget
extends
SingleChildRenderObjectWidget
{
const
_
ButtonRedirectingHitDetectionWidget
({
///
A widget to pad the area around a [MaterialButton]'s inner [Material].
///
///
Redirect taps that occur in the padded area around the child to the center
///
of the child. This increases the size of the button and the button's
///
"tap target", but not its material or its ink splashes
.
class
_
InputPadding
extends
SingleChildRenderObjectWidget
{
const
_
InputPadding
({
Key
key
,
Widget
child
,
this
.
constraints
this
.
minSize
,
})
:
super
(
key:
key
,
child:
child
);
final
BoxConstraints
constraints
;
final
Size
minSize
;
@override
RenderObject
createRenderObject
(
BuildContext
context
)
{
return
new
_Render
ButtonRedirectingHitDetection
(
constraints
);
return
new
_Render
InputPadding
(
minSize
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
covariant
_Render
ButtonRedirectingHitDetection
renderObject
)
{
renderObject
.
additionalConstraints
=
constraints
;
void
updateRenderObject
(
BuildContext
context
,
covariant
_Render
InputPadding
renderObject
)
{
renderObject
.
minSize
=
minSize
;
}
}
class
_RenderButtonRedirectingHitDetection
extends
RenderConstrainedBox
{
_RenderButtonRedirectingHitDetection
(
BoxConstraints
additionalConstraints
)
:
super
(
additionalConstraints:
additionalConstraints
);
class
_RenderInputPadding
extends
RenderShiftedBox
{
_RenderInputPadding
(
this
.
_minSize
,
[
RenderBox
child
])
:
super
(
child
)
;
Size
get
minSize
=>
_minSize
;
Size
_minSize
;
set
minSize
(
Size
value
)
{
if
(
_minSize
==
value
)
return
;
_minSize
=
value
;
markNeedsLayout
();
}
@override
double
computeMinIntrinsicWidth
(
double
height
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
.
computeMinIntrinsicWidth
(
height
),
minSize
.
width
);
return
0.0
;
}
@override
double
computeMinIntrinsicHeight
(
double
width
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
.
computeMinIntrinsicHeight
(
width
),
minSize
.
height
);
return
0.0
;
}
@override
double
computeMaxIntrinsicWidth
(
double
height
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
.
computeMaxIntrinsicWidth
(
height
),
minSize
.
width
);
return
0.0
;
}
@override
double
computeMaxIntrinsicHeight
(
double
width
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
.
computeMaxIntrinsicHeight
(
width
),
minSize
.
height
);
return
0.0
;
}
@override
void
performLayout
()
{
if
(
child
!=
null
)
{
child
.
layout
(
constraints
,
parentUsesSize:
true
);
final
double
height
=
math
.
max
(
child
.
size
.
width
,
minSize
.
width
);
final
double
width
=
math
.
max
(
child
.
size
.
height
,
minSize
.
height
);
size
=
constraints
.
constrain
(
new
Size
(
height
,
width
));
final
BoxParentData
childParentData
=
child
.
parentData
;
childParentData
.
offset
=
Alignment
.
center
.
alongOffset
(
size
-
child
.
size
);
}
else
{
size
=
Size
.
zero
;
}
}
@override
bool
hitTest
(
HitTestResult
result
,
{
Offset
position
})
{
if
(!
size
.
contains
(
position
))
return
false
;
if
(
child
.
hitTest
(
result
,
position:
position
))
return
true
;
return
child
.
hitTest
(
result
,
position:
size
.
center
(
Offset
.
zero
));
return
super
.
hitTest
(
result
,
position:
position
)
||
child
.
hitTest
(
result
,
position:
child
.
size
.
center
(
Offset
.
zero
));
}
}
packages/flutter/test/material/raw_material_button_test.dart
View file @
eb69f594
...
...
@@ -66,14 +66,16 @@ void main() {
const
Color
fillColor
=
const
Color
(
0xFFEF5350
);
await
tester
.
pumpWidget
(
new
RawMaterialButton
(
materialTapTargetSize:
MaterialTapTargetSize
.
padded
,
onPressed:
()
{},
fillColor:
fillColor
,
highlightColor:
highlightColor
,
splashColor:
splashColor
,
child:
const
SizedBox
(),
)
new
Center
(
child:
new
RawMaterialButton
(
materialTapTargetSize:
MaterialTapTargetSize
.
padded
,
onPressed:
()
{},
fillColor:
fillColor
,
highlightColor:
highlightColor
,
splashColor:
splashColor
,
child:
const
SizedBox
(),
),
),
);
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
InkWell
));
...
...
@@ -93,14 +95,16 @@ void main() {
const
Color
fillColor
=
const
Color
(
0xFFEF5350
);
await
tester
.
pumpWidget
(
new
RawMaterialButton
(
materialTapTargetSize:
MaterialTapTargetSize
.
padded
,
onPressed:
()
{},
fillColor:
fillColor
,
highlightColor:
highlightColor
,
splashColor:
splashColor
,
child:
const
SizedBox
(),
)
new
Center
(
child:
new
RawMaterialButton
(
materialTapTargetSize:
MaterialTapTargetSize
.
padded
,
onPressed:
()
{},
fillColor:
fillColor
,
highlightColor:
highlightColor
,
splashColor:
splashColor
,
child:
const
SizedBox
(),
),
),
);
final
Offset
top
=
tester
.
getRect
(
find
.
byType
(
InkWell
)).
topCenter
;
...
...
@@ -117,6 +121,7 @@ void main() {
await
tester
.
pumpWidget
(
new
MaterialApp
(
home:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
<
Widget
>[
new
RawMaterialButton
(
materialTapTargetSize:
MaterialTapTargetSize
.
padded
,
...
...
@@ -165,4 +170,24 @@ void main() {
);
expect
(
find
.
byKey
(
key
).
hitTestable
(),
findsOneWidget
);
});
}
\ No newline at end of file
testWidgets
(
'RawMaterialButton can be expanded by parent constraints'
,
(
WidgetTester
tester
)
async
{
const
Key
key
=
const
Key
(
'test'
);
await
tester
.
pumpWidget
(
new
MaterialApp
(
home:
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
new
RawMaterialButton
(
key:
key
,
onPressed:
()
{},
child:
const
SizedBox
(),
)
],
),
),
);
expect
(
tester
.
getSize
(
find
.
byKey
(
key
)),
const
Size
(
800.0
,
48.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