Commit 2d6f268d authored by xster's avatar xster Committed by Todd Volkert

Revert "Let translucent Cupertino bars have its scaffold children...

Revert "Let translucent Cupertino bars have its scaffold children automatically pad their heights (#13194)" (#13317)

This reverts commit 5c4ffa13.
parent 6db83307
......@@ -131,21 +131,17 @@ class CupertinoDemoTab1 extends StatelessWidget {
largeTitle: const Text('Colors'),
trailing: const ExitButton(),
),
new SliverPadding(
// Top media query padding already consumed by CupertinoSliverNavigationBar.
padding: MediaQuery.of(context).removePadding(removeTop: true).padding,
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Tab1RowItem(
index: index,
lastItem: index == 49,
color: colorItems[index],
colorName: colorNameItems[index],
);
},
childCount: 50,
),
new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Tab1RowItem(
index: index,
lastItem: index == 49,
color: colorItems[index],
colorName: colorNameItems[index],
);
},
childCount: 50,
),
),
],
......@@ -275,7 +271,7 @@ class Tab1ItemPageState extends State<Tab1ItemPage> {
),
child: new ListView(
children: <Widget>[
const Padding(padding: const EdgeInsets.only(top: 16.0)),
const Padding(padding: const EdgeInsets.only(top: 80.0)),
new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new Row(
......@@ -400,6 +396,7 @@ class CupertinoDemoTab2 extends StatelessWidget {
),
child: new ListView(
children: <Widget>[
const Padding(padding: const EdgeInsets.only(top: 60.0)),
new Tab2Header(),
]..addAll(buildTab2Conversation()),
),
......@@ -667,6 +664,7 @@ List<Widget> buildTab2Conversation() {
const Tab2ConversationRow(
text: "What's that?",
),
const Padding(padding: const EdgeInsets.only(bottom: 80.0)),
];
}
......@@ -682,7 +680,7 @@ class CupertinoDemoTab3 extends StatelessWidget {
decoration: const BoxDecoration(color: const Color(0xFFEFEFF4)),
child: new ListView(
children: <Widget>[
const Padding(padding: const EdgeInsets.only(top: 32.0)),
const Padding(padding: const EdgeInsets.only(top: 100.0)),
new GestureDetector(
onTap: () {
Navigator.of(context, rootNavigator: true).push(
......
......@@ -11,7 +11,6 @@ import 'package:flutter/widgets.dart';
import 'button.dart';
import 'colors.dart';
import 'icons.dart';
import 'page_scaffold.dart';
/// Standard iOS navigation bar height without the status bar.
const double _kNavBarPersistentHeight = 44.0;
......@@ -69,7 +68,7 @@ const TextStyle _kLargeTitleTextStyle = const TextStyle(
/// [CupertinoNavigationBar].
/// * [CupertinoSliverNavigationBar] for a navigation bar to be placed in a
/// scrolling list and that supports iOS-11-style large titles.
class CupertinoNavigationBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
class CupertinoNavigationBar extends StatelessWidget implements PreferredSizeWidget {
/// Creates a navigation bar in the iOS style.
const CupertinoNavigationBar({
Key key,
......@@ -117,12 +116,11 @@ class CupertinoNavigationBar extends StatelessWidget implements ObstructingPrefe
final Color actionsForegroundColor;
/// True if the navigation bar's background color has no transparency.
@override
bool get fullObstruction => backgroundColor.alpha == 0xFF;
bool get opaque => backgroundColor.alpha == 0xFF;
@override
Size get preferredSize {
return const Size.fromHeight(_kNavBarPersistentHeight);
return opaque ? const Size.fromHeight(_kNavBarPersistentHeight) : Size.zero;
}
@override
......
......@@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'nav_bar.dart';
/// Implements a single iOS application page's layout.
///
......@@ -31,52 +32,41 @@ class CupertinoPageScaffold extends StatelessWidget {
///
/// If translucent, the main content may slide behind it.
/// Otherwise, the main content's top margin will be offset by its height.
///
/// The scaffold assumes the nav bar will consume the [MediaQuery] top padding.
// TODO(xster): document its page transition animation when ready
final ObstructingPreferredSizeWidget navigationBar;
final PreferredSizeWidget navigationBar;
/// Widget to show in the main content area.
///
/// Content can slide under the [navigationBar] when they're translucent with
/// a [MediaQuery] padding hinting the top obstructed area.
/// Content can slide under the [navigationBar] when they're translucent.
final Widget child;
@override
Widget build(BuildContext context) {
final List<Widget> stacked = <Widget>[];
Widget childWithMediaQuery = child;
Widget paddedContent = child;
double topPadding = 0.0;
if (navigationBar != null) {
final MediaQueryData existingMediaQuery = MediaQuery.of(context);
// TODO(https://github.com/flutter/flutter/issues/12912):
// Use real size after partial layout instead of preferred size.
final double topPadding = navigationBar.preferredSize.height
+ existingMediaQuery.padding.top;
// If nav bar is opaquely obstructing, directly shift the main content
// down. If translucent, let main content draw behind nav bar but hint the
// obstructed area.
if (navigationBar.fullObstruction) {
paddedContent = new Padding(
padding: new EdgeInsets.only(top: topPadding),
child: child,
);
} else {
paddedContent = new MediaQuery(
data: existingMediaQuery.copyWith(
padding: existingMediaQuery.padding.copyWith(
top: topPadding,
),
),
topPadding += navigationBar.preferredSize.height;
// If the navigation bar has a preferred size, pad it and the OS status
// bar as well. Otherwise, let the content extend to the complete top
// of the page.
if (topPadding > 0.0) {
final EdgeInsets mediaQueryPadding = MediaQuery.of(context).padding;
topPadding += mediaQueryPadding.top;
childWithMediaQuery = new MediaQuery.removePadding(
context: context,
removeTop: true,
child: child,
);
}
}
// The main content being at the bottom is added to the stack first.
stacked.add(paddedContent);
stacked.add(new Padding(
padding: new EdgeInsets.only(top: topPadding),
child: childWithMediaQuery,
));
if (navigationBar != null) {
stacked.add(new Positioned(
......@@ -94,14 +84,4 @@ class CupertinoPageScaffold extends StatelessWidget {
),
);
}
}
/// Widget that has a preferred size and reports whether it fully obstructs
/// widgets behind it.
abstract class ObstructingPreferredSizeWidget extends PreferredSizeWidget {
/// If true, this widget fully obstructs widgets behind it by the specified
/// size.
///
/// If false, this widget partially obstructs.
bool get fullObstruction;
}
}
\ No newline at end of file
......@@ -117,8 +117,7 @@ class CupertinoTabScaffold extends StatefulWidget {
/// When the tab becomes inactive, its content is still cached in the widget
/// tree [Offstage] and its animations disabled.
///
/// Content can slide under the [tabBar] when it's translucent with a
/// [MediaQuery] padding hinting the bottom obstructed area.
/// Content can slide under the [tabBar] when it's translucent.
final IndexedWidgetBuilder tabBuilder;
@override
......@@ -132,42 +131,17 @@ class _CupertinoTabScaffoldState extends State<CupertinoTabScaffold> {
Widget build(BuildContext context) {
final List<Widget> stacked = <Widget>[];
Widget content = new _TabView(
currentTabIndex: _currentPage,
tabNumber: widget.tabBar.items.length,
tabBuilder: widget.tabBuilder,
);
if (widget.tabBar != null) {
final MediaQueryData existingMediaQuery = MediaQuery.of(context);
// TODO(https://github.com/flutter/flutter/issues/12912):
// Use real size after partial layout instead of preferred size.
final double bottomPadding = widget.tabBar.preferredSize.height
+ existingMediaQuery.padding.bottom;
// If tab bar opaque, directly stop the main content higher. If
// translucent, let main content draw behind the tab bar but hint the
// obstructed area.
if (widget.tabBar.opaque) {
content = new Padding(
padding: new EdgeInsets.only(bottom: bottomPadding),
child: content,
);
} else {
content = new MediaQuery(
data: existingMediaQuery.copyWith(
padding: existingMediaQuery.padding.copyWith(
bottom: bottomPadding,
),
),
child: content,
);
}
}
// The main content being at the bottom is added to the stack first.
stacked.add(content);
stacked.add(
new Padding(
padding: new EdgeInsets.only(bottom: widget.tabBar.opaque ? widget.tabBar.preferredSize.height : 0.0),
child: new _TabView(
currentTabIndex: _currentPage,
tabNumber: widget.tabBar.items.length,
tabBuilder: widget.tabBuilder,
)
),
);
if (widget.tabBar != null) {
stacked.add(new Align(
......
......@@ -7,7 +7,6 @@ import 'package:flutter/rendering.dart';
import 'basic.dart';
import 'framework.dart';
import 'media_query.dart';
import 'primary_scroll_controller.dart';
import 'scroll_controller.dart';
import 'scroll_physics.dart';
......@@ -373,33 +372,8 @@ abstract class BoxScrollView extends ScrollView {
@override
List<Widget> buildSlivers(BuildContext context) {
Widget sliver = buildChildLayout(context);
EdgeInsetsGeometry effectivePadding = padding;
if (padding == null) {
final MediaQueryData mediaQuery = MediaQuery.of(context, nullOk: true);
if (mediaQuery != null) {
// Automatically pad sliver with padding from MediaQuery.
final EdgeInsets mediaQueryHorizontalPadding =
mediaQuery.padding.copyWith(top: 0.0, bottom: 0.0);
final EdgeInsets mediaQueryVerticalPadding =
mediaQuery.padding.copyWith(left: 0.0, right: 0.0);
// Consume the main axis padding with SliverPadding.
effectivePadding = scrollDirection == Axis.vertical
? mediaQueryVerticalPadding
: mediaQueryHorizontalPadding;
// Leave behind the cross axis padding.
sliver = new MediaQuery(
data: mediaQuery.copyWith(
padding: scrollDirection == Axis.vertical
? mediaQueryHorizontalPadding
: mediaQueryVerticalPadding,
),
child: sliver,
);
}
}
if (effectivePadding != null)
sliver = new SliverPadding(padding: effectivePadding, sliver: sliver);
if (padding != null)
sliver = new SliverPadding(padding: padding, sliver: sliver);
return <Widget>[ sliver ];
}
......
......@@ -78,66 +78,6 @@ void main() {
expect(tester.getSize(find.byWidget(page1Center)).height, 600.0 - 44.0 - 50.0);
});
testWidgets('Contents have automatic sliver padding between translucent bars', (WidgetTester tester) async {
final Container content = new Container(height: 600.0, width: 600.0);
await tester.pumpWidget(
new WidgetsApp(
color: const Color(0xFFFFFFFF),
onGenerateRoute: (RouteSettings settings) {
return new CupertinoPageRoute<Null>(
settings: settings,
builder: (BuildContext context) {
return new MediaQuery(
data: const MediaQueryData(
padding: const EdgeInsets.symmetric(vertical: 20.0),
),
child: new CupertinoTabScaffold(
tabBar: new CupertinoTabBar(
items: <BottomNavigationBarItem>[
const BottomNavigationBarItem(
icon: const ImageIcon(const TestImageProvider(24, 24)),
title: const Text('Tab 1'),
),
const BottomNavigationBarItem(
icon: const ImageIcon(const TestImageProvider(24, 24)),
title: const Text('Tab 2'),
),
],
),
tabBuilder: (BuildContext context, int index) {
return index == 0
? new CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: const Text('Title'),
),
child: new ListView(
children: <Widget>[
content,
],
),
)
: new Stack();
}
),
);
},
);
},
),
);
// List content automatically padded by nav bar and top media query padding.
expect(tester.getTopLeft(find.byWidget(content)).dy, 20.0 + 44.0);
// Overscroll to the bottom.
await tester.drag(find.byWidget(content), const Offset(0.0, -400.0));
await tester.pump(const Duration(seconds: 1));
// List content automatically padded by tab bar and bottom media query padding.
expect(tester.getBottomLeft(find.byWidget(content)).dy, 600 - 20.0 - 50.0);
});
testWidgets('iOS independent tab navigation', (WidgetTester tester) async {
// A full on iOS information architecture app with 2 tabs, and 2 pages
// in each with independent navigation states.
......
......@@ -265,32 +265,4 @@ void main() {
expect(delegate.log, equals(<String>['didFinishLayout firstIndex=2 lastIndex=5']));
delegate.log.clear();
});
testWidgets('ListView automatically pad MediaQuery on axis', (WidgetTester tester) async {
EdgeInsets innerMediaQueryPadding;
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new MediaQuery(
data: const MediaQueryData(
padding: const EdgeInsets.all(30.0),
),
child: new ListView(
children: <Widget>[
const Text('top', textDirection: TextDirection.ltr),
new Builder(builder: (BuildContext context) {
innerMediaQueryPadding = MediaQuery.of(context).padding;
return new Container();
}),
],
),
),
),
);
// Automatically apply the top/bottom padding into sliver.
expect(tester.getTopLeft(find.text('top')).dy, 30.0);
// Leave left/right padding as is for children.
expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
});
}
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