Commit 9bc64540 authored by Adam Barth's avatar Adam Barth

Improve hit testing

Now a RenderBox is considered hit if one of its children are hit or it itself
decides that it's hit. In particular, empty space inside a flex won't be hit
because none of the children are located there and a RenderFlex doesn't
consider itself hittable.

Fixes #53
Fixes #1221
parent 7b36d944
...@@ -22,6 +22,8 @@ class IconButton extends StatelessComponent { ...@@ -22,6 +22,8 @@ class IconButton extends StatelessComponent {
final VoidCallback onPressed; final VoidCallback onPressed;
Widget build(BuildContext context) { Widget build(BuildContext context) {
// TODO(abarth): We should use a radial reaction here so you can hit the
// 8.0 pixel padding as well as the icon.
return new GestureDetector( return new GestureDetector(
onTap: onPressed, onTap: onPressed,
child: new Padding( child: new Padding(
......
...@@ -248,6 +248,8 @@ class _RenderInkSplashes extends RenderProxyBox { ...@@ -248,6 +248,8 @@ class _RenderInkSplashes extends RenderProxyBox {
onLongPress(); onLongPress();
} }
bool hitTestSelf(Point position) => true;
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (!_splashes.isEmpty) { if (!_splashes.isEmpty) {
final PaintingCanvas canvas = context.canvas; final PaintingCanvas canvas = context.canvas;
......
...@@ -205,8 +205,8 @@ class _RenderTabBar extends RenderBox with ...@@ -205,8 +205,8 @@ class _RenderTabBar extends RenderBox with
reportLayoutChangedIfNeeded(); reportLayoutChangedIfNeeded();
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
void _paintIndicator(PaintingCanvas canvas, RenderBox selectedTab, Offset offset) { void _paintIndicator(PaintingCanvas canvas, RenderBox selectedTab, Offset offset) {
......
...@@ -219,8 +219,8 @@ class RenderAutoLayout extends RenderBox ...@@ -219,8 +219,8 @@ class RenderAutoLayout extends RenderBox
// only indicates that the value has been flushed to the variable. // only indicates that the value has been flushed to the variable.
} }
void hitTestChildren(HitTestResult result, {Point position}) { bool hitTestChildren(HitTestResult result, {Point position}) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
......
...@@ -219,8 +219,8 @@ class RenderBlock extends RenderBlockBase { ...@@ -219,8 +219,8 @@ class RenderBlock extends RenderBlockBase {
defaultPaint(context, offset); defaultPaint(context, offset);
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
} }
...@@ -423,11 +423,11 @@ class RenderBlockViewport extends RenderBlockBase { ...@@ -423,11 +423,11 @@ class RenderBlockViewport extends RenderBlockBase {
transform.translate(startOffset, 0.0); transform.translate(startOffset, 0.0);
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (isVertical) if (isVertical)
defaultHitTestChildren(result, position: position + new Offset(0.0, -startOffset)); return defaultHitTestChildren(result, position: position + new Offset(0.0, -startOffset));
else else
defaultHitTestChildren(result, position: position + new Offset(-startOffset, 0.0)); return defaultHitTestChildren(result, position: position + new Offset(-startOffset, 0.0));
} }
void debugDescribeSettings(List<String> settings) { void debugDescribeSettings(List<String> settings) {
......
...@@ -545,20 +545,25 @@ abstract class RenderBox extends RenderObject { ...@@ -545,20 +545,25 @@ abstract class RenderBox extends RenderObject {
bool hitTest(HitTestResult result, { Point position }) { bool hitTest(HitTestResult result, { Point position }) {
if (position.x >= 0.0 && position.x < _size.width && if (position.x >= 0.0 && position.x < _size.width &&
position.y >= 0.0 && position.y < _size.height) { position.y >= 0.0 && position.y < _size.height) {
hitTestChildren(result, position: position); if (hitTestChildren(result, position: position) || hitTestSelf(position)) {
result.add(new BoxHitTestEntry(this, position)); result.add(new BoxHitTestEntry(this, position));
return true; return true;
}
} }
return false; return false;
} }
/// Override this function if this render object can be hit even if its
/// children were not hit
bool hitTestSelf(Point position) => false;
/// Override this function to check whether any children are located at the /// Override this function to check whether any children are located at the
/// given position /// given position
/// ///
/// Typically children should be hit tested in reverse paint order so that /// Typically children should be hit tested in reverse paint order so that
/// hit tests at locations where children overlap hit the child that is /// hit tests at locations where children overlap hit the child that is
/// visually "on top" (i.e., paints later). /// visually "on top" (i.e., paints later).
void hitTestChildren(HitTestResult result, { Point position }) { } bool hitTestChildren(HitTestResult result, { Point position }) => false;
/// Multiply the transform from the parent's coordinate system to this box's /// Multiply the transform from the parent's coordinate system to this box's
/// coordinate system into the given transform /// coordinate system into the given transform
......
...@@ -108,7 +108,7 @@ class RenderCustomMultiChildLayoutBox extends RenderBox ...@@ -108,7 +108,7 @@ class RenderCustomMultiChildLayoutBox extends RenderBox
defaultPaint(context, offset); defaultPaint(context, offset);
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
} }
...@@ -30,6 +30,8 @@ class RenderErrorBox extends RenderBox { ...@@ -30,6 +30,8 @@ class RenderErrorBox extends RenderBox {
bool get sizedByParent => true; bool get sizedByParent => true;
bool hitTestSelf(Point position) => true;
void performResize() { void performResize() {
size = constraints.constrain(const Size(_kMaxWidth, _kMaxHeight)); size = constraints.constrain(const Size(_kMaxWidth, _kMaxHeight));
} }
......
...@@ -542,8 +542,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -542,8 +542,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
} }
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
......
...@@ -134,8 +134,8 @@ class RenderGrid extends RenderBox with ContainerRenderObjectMixin<RenderBox, Gr ...@@ -134,8 +134,8 @@ class RenderGrid extends RenderBox with ContainerRenderObjectMixin<RenderBox, Gr
} }
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
......
...@@ -179,6 +179,8 @@ class RenderImage extends RenderBox { ...@@ -179,6 +179,8 @@ class RenderImage extends RenderBox {
return _sizeForConstraints(constraints).height; return _sizeForConstraints(constraints).height;
} }
bool hitTestSelf(Point position) => true;
void performLayout() { void performLayout() {
size = _sizeForConstraints(constraints); size = _sizeForConstraints(constraints);
} }
......
...@@ -125,11 +125,8 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render ...@@ -125,11 +125,8 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render
child.layout(_getInnerConstraints(constraints)); child.layout(_getInnerConstraints(constraints));
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (child != null) return child?.hitTest(result, position: position) ?? false;
child.hitTest(result, position: position);
else
super.hitTestChildren(result, position: position);
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
...@@ -195,11 +192,8 @@ class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<R ...@@ -195,11 +192,8 @@ class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<R
child.layout(constraints); child.layout(constraints);
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (child != null) return child?.hitTest(result, position: position) ?? false;
child.hitTest(result, position: position);
else
super.hitTestChildren(result, position: position);
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
......
...@@ -96,6 +96,8 @@ class RenderParagraph extends RenderBox { ...@@ -96,6 +96,8 @@ class RenderParagraph extends RenderBox {
return textPainter.computeDistanceToActualBaseline(baseline); return textPainter.computeDistanceToActualBaseline(baseline);
} }
bool hitTestSelf(Point position) => true;
void performLayout() { void performLayout() {
layoutText(constraints); layoutText(constraints);
size = constraints.constrain(textPainter.size); size = constraints.constrain(textPainter.size);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
...@@ -70,11 +71,8 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox ...@@ -70,11 +71,8 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
} }
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (child != null) return child?.hitTest(result, position: position) ?? false;
child.hitTest(result, position: position);
else
super.hitTestChildren(result, position: position);
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
...@@ -625,6 +623,15 @@ class RenderClipOval extends RenderProxyBox { ...@@ -625,6 +623,15 @@ class RenderClipOval extends RenderProxyBox {
return _cachedPath; return _cachedPath;
} }
bool hitTest(HitTestResult result, { Point position }) {
Point center = size.center(Point.origin);
Offset offset = new Offset((position.x - center.x) / size.width,
(position.y - center.y) / size.height);
if (offset.distance > 0.5)
return false;
return super.hitTest(result, position: position);
}
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
Rect rect = offset & size; Rect rect = offset & size;
...@@ -706,6 +713,19 @@ class RenderDecoratedBox extends RenderProxyBox { ...@@ -706,6 +713,19 @@ class RenderDecoratedBox extends RenderProxyBox {
super.detach(); super.detach();
} }
bool hitTestSelf(Point position) {
switch (_painter.decoration.shape) {
case Shape.rectangle:
// TODO(abarth): We should check the border radius.
return true;
case Shape.circle:
// Circles are inscribed into our smallest dimension.
Point center = size.center(Point.origin);
double distance = (position - center).distance;
return distance <= math.min(size.width, size.height) / 2.0;
}
}
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
assert(size.width != null); assert(size.width != null);
assert(size.height != null); assert(size.height != null);
...@@ -894,6 +914,7 @@ class RenderSizeObserver extends RenderProxyBox { ...@@ -894,6 +914,7 @@ class RenderSizeObserver extends RenderProxyBox {
/// Called when its time to paint into the given canvas /// Called when its time to paint into the given canvas
typedef void CustomPaintCallback(PaintingCanvas canvas, Size size); typedef void CustomPaintCallback(PaintingCanvas canvas, Size size);
typedef bool CustomHitTestCallback(Point position);
/// Delegates its painting to [onPaint] /// Delegates its painting to [onPaint]
/// ///
...@@ -911,6 +932,7 @@ class RenderCustomPaint extends RenderProxyBox { ...@@ -911,6 +932,7 @@ class RenderCustomPaint extends RenderProxyBox {
RenderCustomPaint({ RenderCustomPaint({
CustomPaintCallback onPaint, CustomPaintCallback onPaint,
this.onHitTest,
RenderBox child RenderBox child
}) : super(child) { }) : super(child) {
assert(onPaint != null); assert(onPaint != null);
...@@ -931,11 +953,17 @@ class RenderCustomPaint extends RenderProxyBox { ...@@ -931,11 +953,17 @@ class RenderCustomPaint extends RenderProxyBox {
markNeedsPaint(); markNeedsPaint();
} }
CustomHitTestCallback onHitTest;
void attach() { void attach() {
assert(_onPaint != null); assert(_onPaint != null);
super.attach(); super.attach();
} }
bool hitTestSelf(Point position) {
return onHitTest == null || onHitTest(position);
}
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
assert(_onPaint != null); assert(_onPaint != null);
context.canvas.translate(offset.dx, offset.dy); context.canvas.translate(offset.dx, offset.dy);
......
...@@ -60,12 +60,14 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi ...@@ -60,12 +60,14 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
} }
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (child != null) { if (child != null) {
final BoxParentData childParentData = child.parentData; final BoxParentData childParentData = child.parentData;
child.hitTest(result, position: new Point(position.x - childParentData.position.x, final Point childPosition = new Point(position.x - childParentData.position.x,
position.y - childParentData.position.y)); position.y - childParentData.position.y);
return child.hitTest(result, position: childPosition);
} }
return false;
} }
} }
......
...@@ -357,8 +357,8 @@ abstract class RenderStackBase extends RenderBox ...@@ -357,8 +357,8 @@ abstract class RenderStackBase extends RenderBox
} }
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position); return defaultHitTestChildren(result, position: position);
} }
void paintStack(PaintingContext context, Offset offset); void paintStack(PaintingContext context, Offset offset);
...@@ -455,15 +455,15 @@ class RenderIndexedStack extends RenderStackBase { ...@@ -455,15 +455,15 @@ class RenderIndexedStack extends RenderStackBase {
return child; return child;
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (firstChild == null) if (firstChild == null)
return; return false;
assert(position != null); assert(position != null);
RenderBox child = _childAtIndex(); RenderBox child = _childAtIndex();
final StackParentData childParentData = child.parentData; final StackParentData childParentData = child.parentData;
Point transformed = new Point(position.x - childParentData.position.x, Point transformed = new Point(position.x - childParentData.position.x,
position.y - childParentData.position.y); position.y - childParentData.position.y);
child.hitTest(result, position: transformed); return child.hitTest(result, position: transformed);
} }
void paintStack(PaintingContext context, Offset offset) { void paintStack(PaintingContext context, Offset offset) {
......
...@@ -73,4 +73,6 @@ abstract class RenderToggleable extends RenderConstrainedBox { ...@@ -73,4 +73,6 @@ abstract class RenderToggleable extends RenderConstrainedBox {
if (onChanged != null) if (onChanged != null)
onChanged(!_value); onChanged(!_value);
} }
bool hitTestSelf(Point position) => true;
} }
...@@ -160,11 +160,12 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox ...@@ -160,11 +160,12 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
transform.translate(-scrollOffset.dx, -scrollOffset.dy); transform.translate(-scrollOffset.dx, -scrollOffset.dy);
} }
void hitTestChildren(HitTestResult result, { Point position }) { bool hitTestChildren(HitTestResult result, { Point position }) {
if (child != null) { if (child != null) {
assert(child.parentData is BoxParentData); assert(child.parentData is BoxParentData);
Point transformed = position + _scrollOffsetRoundedToIntegerDevicePixels; Point transformed = position + _scrollOffsetRoundedToIntegerDevicePixels;
child.hitTest(result, position: transformed); return child.hitTest(result, position: transformed);
} }
return false;
} }
} }
...@@ -138,7 +138,7 @@ class DecoratedBox extends OneChildRenderObjectWidget { ...@@ -138,7 +138,7 @@ class DecoratedBox extends OneChildRenderObjectWidget {
} }
class CustomPaint extends OneChildRenderObjectWidget { class CustomPaint extends OneChildRenderObjectWidget {
CustomPaint({ Key key, this.onPaint, this.token, Widget child }) CustomPaint({ Key key, this.onPaint, this.onHitTest, this.token, Widget child })
: super(key: key, child: child) { : super(key: key, child: child) {
assert(onPaint != null); assert(onPaint != null);
} }
...@@ -151,19 +151,23 @@ class CustomPaint extends OneChildRenderObjectWidget { ...@@ -151,19 +151,23 @@ class CustomPaint extends OneChildRenderObjectWidget {
/// has a more stable identity. /// has a more stable identity.
final CustomPaintCallback onPaint; final CustomPaintCallback onPaint;
final CustomHitTestCallback onHitTest;
/// This widget repaints whenever you supply a new token. /// This widget repaints whenever you supply a new token.
final Object token; final Object token;
RenderCustomPaint createRenderObject() => new RenderCustomPaint(onPaint: onPaint); RenderCustomPaint createRenderObject() => new RenderCustomPaint(onPaint: onPaint, onHitTest: onHitTest);
void updateRenderObject(RenderCustomPaint renderObject, CustomPaint oldWidget) { void updateRenderObject(RenderCustomPaint renderObject, CustomPaint oldWidget) {
if (oldWidget.token != token) if (oldWidget.token != token)
renderObject.markNeedsPaint(); renderObject.markNeedsPaint();
renderObject.onPaint = onPaint; renderObject.onPaint = onPaint;
renderObject.onHitTest = onHitTest;
} }
void didUnmountRenderObject(RenderCustomPaint renderObject) { void didUnmountRenderObject(RenderCustomPaint renderObject) {
renderObject.onPaint = null; renderObject.onPaint = null;
renderObject.onHitTest = null;
} }
} }
......
...@@ -17,29 +17,23 @@ const Color _kTransparent = const Color(0x00000000); ...@@ -17,29 +17,23 @@ const Color _kTransparent = const Color(0x00000000);
class ModalBarrier extends StatelessComponent { class ModalBarrier extends StatelessComponent {
ModalBarrier({ ModalBarrier({
Key key, Key key,
this.color this.color: _kTransparent
}) : super(key: key); }) : super(key: key);
final Color color; final Color color;
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget child;
if (color != null) {
child = new DecoratedBox(
decoration: new BoxDecoration(
backgroundColor: color
)
);
}
return new Listener( return new Listener(
onPointerDown: (_) { onPointerDown: (_) {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: new ConstrainedBox( child: new ConstrainedBox(
constraints: const BoxConstraints.expand(), constraints: const BoxConstraints.expand(),
child: child child: new DecoratedBox(
decoration: new BoxDecoration(
backgroundColor: color
)
)
) )
); );
} }
......
...@@ -5,8 +5,14 @@ import 'rendering_tester.dart'; ...@@ -5,8 +5,14 @@ import 'rendering_tester.dart';
void main() { void main() {
test('Should be able to hit with negative scroll offset', () { test('Should be able to hit with negative scroll offset', () {
RenderBox green = new RenderDecoratedBox(
decoration: new BoxDecoration(
backgroundColor: const Color(0xFF00FF00)
));
RenderBox size = new RenderConstrainedBox( RenderBox size = new RenderConstrainedBox(
additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0))); additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0)),
child: green);
RenderBox red = new RenderDecoratedBox( RenderBox red = new RenderDecoratedBox(
decoration: new BoxDecoration( decoration: new BoxDecoration(
...@@ -21,10 +27,10 @@ void main() { ...@@ -21,10 +27,10 @@ void main() {
result = new HitTestResult(); result = new HitTestResult();
renderView.hitTest(result, position: new Point(15.0, 0.0)); renderView.hitTest(result, position: new Point(15.0, 0.0));
expect(result.path.first.target, equals(viewport)); expect(result.path.first.target.runtimeType, equals(TestRenderView));
result = new HitTestResult(); result = new HitTestResult();
renderView.hitTest(result, position: new Point(15.0, 15.0)); renderView.hitTest(result, position: new Point(15.0, 15.0));
expect(result.path.first.target, equals(size)); expect(result.path.first.target, equals(green));
}); });
} }
...@@ -23,7 +23,11 @@ void main() { ...@@ -23,7 +23,11 @@ void main() {
onVerticalDragEnd: (Offset velocity) { onVerticalDragEnd: (Offset velocity) {
didEndDrag = true; didEndDrag = true;
}, },
child: new Container() child: new Container(
decoration: const BoxDecoration(
backgroundColor: const Color(0xFF00FF00)
)
)
); );
tester.pumpWidget(widget); tester.pumpWidget(widget);
...@@ -70,7 +74,11 @@ void main() { ...@@ -70,7 +74,11 @@ void main() {
onVerticalDragEnd: (Offset velocity) { gestureCount += 1; }, onVerticalDragEnd: (Offset velocity) { gestureCount += 1; },
onHorizontalDragUpdate: (_) { fail("gesture should not match"); }, onHorizontalDragUpdate: (_) { fail("gesture should not match"); },
onHorizontalDragEnd: (Offset velocity) { fail("gesture should not match"); }, onHorizontalDragEnd: (Offset velocity) { fail("gesture should not match"); },
child: new Container() child: new Container(
decoration: const BoxDecoration(
backgroundColor: const Color(0xFF00FF00)
)
)
); );
tester.pumpWidget(widget); tester.pumpWidget(widget);
...@@ -106,7 +114,11 @@ void main() { ...@@ -106,7 +114,11 @@ void main() {
onPanEnd: (_) { onPanEnd: (_) {
didEndPan = true; didEndPan = true;
}, },
child: new Container() child: new Container(
decoration: const BoxDecoration(
backgroundColor: const Color(0xFF00FF00)
)
)
) )
); );
......
...@@ -21,9 +21,14 @@ void main() { ...@@ -21,9 +21,14 @@ void main() {
content: new Text(helloSnackBar) content: new Text(helloSnackBar)
); );
}, },
child: new Center( child: new Container(
key: tapTarget, decoration: const BoxDecoration(
child: new Placeholder(key: placeholderKey) backgroundColor: const Color(0xFF00FF00)
),
child: new Center(
key: tapTarget,
child: new Placeholder(key: placeholderKey)
)
) )
); );
} }
......
...@@ -33,7 +33,11 @@ void main() { ...@@ -33,7 +33,11 @@ void main() {
onTap: () { onTap: () {
didReceiveTap = true; didReceiveTap = true;
}, },
child: new Container() child: new Container(
decoration: new BoxDecoration(
backgroundColor: new Color(0xFF00FFFF)
)
)
) )
) )
) )
...@@ -78,7 +82,11 @@ void main() { ...@@ -78,7 +82,11 @@ void main() {
onTap: () { onTap: () {
didReceiveTap = true; didReceiveTap = true;
}, },
child: new Container() child: new Container(
decoration: new BoxDecoration(
backgroundColor: new Color(0xFF00FFFF)
)
)
) )
) )
) )
...@@ -124,7 +132,11 @@ void main() { ...@@ -124,7 +132,11 @@ void main() {
onTap: () { onTap: () {
didReceiveTap = true; didReceiveTap = true;
}, },
child: new Container() child: new Container(
decoration: new BoxDecoration(
backgroundColor: new Color(0xFF00FFFF)
)
)
) )
) )
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment