Skip to content

Conversation

@nataliesampsell
Copy link

@nataliesampsell nataliesampsell commented Jul 10, 2018

-Add showCupertinoModalPopup, CupertinoActionSheet

import 'colors.dart';
import 'scrollbar.dart';

const TextStyle _kCupertinoActionSheetActionTextStyle = const TextStyle(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't really need to have such a long name here, since it's local to this file: _kActionTextStyle would be fine.


void _onTap() {
widget.onPressed;
Navigator.pop(context); //SHOULD THE ACTION SHEET BE HANDLING THIS?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the onPressed will handle that. Look at how the dialog demo in the gallery does it. In order to do it here, you'd have to know what value to pass back.

}

void _onTap() {
widget.onPressed;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be widget.onPressed(); (or it won't actually call the function).

AnimationController createAnimationController() {
assert(_animationController == null);
_animationController = new AnimationController(
duration: const Duration(milliseconds: 500),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels too long to me, but if that's what iOS does, then it's fine.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are correct, was waiting to play with duration and curve until I got the positioning of the sheet correct (should have made a note of this)!


return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: new Center(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's your problem with getting the child size in your layout's getPositionForChild. The Center is expanding to fill the whole available area. Just remove this Center.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, that worked! Do you think making that change will help with my sizing problem if I continue to play around with constraints?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it should. Give it a try.

Copy link
Member

@xster xster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a quick look at the route.dart part

}) {
return Navigator.push(context, new _CupertinoModalPopupRoute<T>(
builder: builder,
barrierLabel: 'ModalPopup',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the announced label for what happens when you tap the barrier. Probably 'dismiss' or something.

}
}

class _ModalBottomSheet<T> extends StatefulWidget {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be Stateful? Can we just collapse this whole thing into _CupertinoModalPopupRoute and avoid a layer of abstraction?

Widget build(BuildContext context) {
return new AnimatedBuilder(
animation: widget.route.animation,
builder: (BuildContext context, Widget child) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building a AnimatedBuilder without using a child is fairly expensive (since the child tree itself needs to rebuild each frame even though the action sheets themselves presumably don't change during the animation).

This setup seems complex. Can't it just be a FractionalTranslation with a child?

@nataliesampsell nataliesampsell changed the title [WIP] Action sheets CupertinoActionSheet Aug 7, 2018
@nataliesampsell
Copy link
Author

nataliesampsell commented Aug 7, 2018

@gspencergoog and @xster I've pushed my latest work on CupertinoActionSheet for your review. Matt requested that I copy any code I was using from his dialog PR (as opposed to me trying to land my work on top of his), so there is overlap between my PR and his - just so you're aware if you are also reviewing his PR.

textBaseline: TextBaseline.alphabetic,
);

// _kCupertinoAlertBlurOverlayDecoration is applied to the blurred backdrop to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Instead of saying _kCupertinoAlertBlurOverlayDecoration, just say "This decoration". That way, if the variable is renamed using a refactoring tool, the name won't be out of sync.


/// An iOS-style action sheet.
///
/// An action sheet is a specific style of alert that present the user
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

present --> presents

/// sheet title and message text style.
///
/// To display action buttons that look like standard iOS action sheet buttons,
/// provide [ActionSheetAction]s for the [actions] given to this action shet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shet --> sheet

}
}

/// A button typically used in an [CupertinoActionSheet].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an --> a
(or should this still be ActionSheet instead of CupertinoActionSheet?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, apologies for all of the ActionSheet/CupertinoActionSheet mixups. I believe it should be CupertinoActionSheet, in keeping with the Cupertino naming convention, but I started with it being ActionSheet and forgot to make the change throughout the comments.

}
}

// iOS style layout policy for sizing an alert's content section and action
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS style --> An iOS-style

///
/// See also:
///
/// * [ActionSheet], which is the widget usually returned by the `builder`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ActionSheet be CupertinoActionSheet? Or is that all happening in the other rename PR?


/// The blend mode applied to the [color] or [gradient] background of the box.
///
/// If no [backgroundBlendMode] is provided then the default painting blend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provided --> provided,
(add comma)

/// If no [backgroundBlendMode] is provided then the default painting blend
/// mode is used.
///
/// If no [color] or [gradient] is provided then blend mode has no impact.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provided --> provided,
(add comma)

///
/// See also:
///
/// * [CupertinoActionSheet], an alert that presents the user with a set of two or
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be ActionSheet instead of CupertinoActionSheet?

///
/// * [CupertinoActionSheet], an alert that presents the user with a set of two or
/// more choices related to the current context.
class ActionSheetAction extends StatelessWidget {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be CupertinoActinoSheetAction?

Copy link
Member

@xster xster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice. Just a few small comments.


Widget _buildCancelButton() {
final double cancelPadding = (actions != null || message != null || title != null)
? _kEdgeHorizontalPadding : 0.0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're reading a thing called horizontal padding but you're only using it vertically it seems.

Widget build(BuildContext context) {
final List<Widget> children = <Widget>[
new Flexible(child: ClipRRect(
borderRadius: BorderRadius.circular(12.0),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use dart2 syntax yet

}
}

class _CupertinoAlertRenderWidget extends RenderObjectWidget {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming everything here below are things copied from @matthew-carroll's PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes everything below is copied, with some modifications to make things work for action sheets specifically

}

Widget createAppWithButtonThatLaunchesActionSheet(Widget actionSheet) {
return new MaterialApp(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using Material widgets here. Just use their Cupertino equivalents

),
);

final DefaultTextStyle widget = tester.widget(find.byType(DefaultTextStyle));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find.widgetWithText to be more precise

await tester.pumpWidget(
createAppWithButtonThatLaunchesActionSheet(
new CupertinoActionSheet(
actions: <Widget>[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indents are a bit off here and above

await tester.pump(const Duration(seconds: 1));

// Check that the title/message section is not displayed
expect(actionScrollController.offset, 0.0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how the actions scroll controller's offset is indicative of the presence or absence of the title/message section


// Check that the button's vertical size is the same.
expect(tester.getSize(find.widgetWithText(CupertinoActionSheetAction, 'One')).height,
equals(tester.getSize(find.widgetWithText(CupertinoActionSheetAction, 'Two')).height));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indent

expect(actionScrollController.offset, 0.0);

// Check that the button's vertical size is the same.
expect(tester.getSize(find.widgetWithText(CupertinoActionSheetAction, 'One')).height,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps check their exact coordinates?

await tester.tap(find.text('Go'));
await tester.pump();

expect(tester.getSize(find.byType(CupertinoActionSheet)).height, 132.33333333333334);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moreOrLessEquals (or it can be undeterministic depending on the machine it's running on)

Copy link
Member

@xster xster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

this.messageScrollController,
this.actionScrollController,
this.cancelButton,
}) : assert(actions != null || title != null || message != null || cancelButton != null),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an error message


if (cancelButton != null) {
children.add(
_buildCancelButton(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no blur behind the cancel button?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, from observation/experimentation I've found that the cancel button isn't transparent like the other buttons.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah cool, thanks for testing

@override
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
if (_animation.value == 1.0) {
context.findRenderObject().markNeedsSemanticsUpdate();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildTransition isn't guaranteed to be called each time the animation value changes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've found in practice that the animation is long enough and the curve is such that buildTransitions ends up being called several times while the animation value is 1.0. I understand the concern though - could the markNeedsSemanticsUpdate() be called in buildPage, or do you know of another way to tell the render object there needs to be a semantics update when the animation is complete?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about dismissal? Don't you want to call it as soon as it's not 1.0 anymore? Add animation status listeners on createAnimation. (Make sure to unregister the listener when it's done though)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually why do you call this here in the route itself? What is the issue you're solving?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking I'd want to call it when the animation was complete so the semantic bounds could be placed correctly? Does that make sense?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, just saw your followup question - the issue is that the semantic bounds for the action sheet end up being drawn offscreen, so I need to have the semantics update once the action sheets get in their final position.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I would leave this out altogether. If it's easy to produce a reduced test case that demonstrates that the semantic box is at the wrong place inside a fractional translation, this should be fixed in the semantics pipeline itself.

I'd leave it broken and leave an issue describing the misbehavior.

return new Align(
alignment: Alignment.bottomCenter,
child: new FractionalTranslation(
translation: new Tween<Offset>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create this once in createAnimation

@nataliesampsell nataliesampsell merged commit 96326d4 into flutter:master Aug 10, 2018
@nataliesampsell nataliesampsell deleted the action_sheets branch August 10, 2018 04:55
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants