mirror of
https://github.com/flutter/samples.git
synced 2025-11-11 07:18:15 +00:00
Add game_template (#1180)
Adds a template / sample for games built in Flutter, with all the bells and whistles, like ads, in-app purchases, audio, main menu, settings, and so on. Co-authored-by: Parker Lougheed Co-authored-by: Shams Zakhour
This commit is contained in:
125
game_template/lib/src/style/responsive_screen.dart
Normal file
125
game_template/lib/src/style/responsive_screen.dart
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright 2022, the Flutter project authors. Please see the AUTHORS file
|
||||
// for details. 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/material.dart';
|
||||
|
||||
/// A widget that makes it easy to create a screen with a square-ish
|
||||
/// main area, a smaller menu area, and a small area for a message on top.
|
||||
/// It works in both orientations on mobile- and tablet-sized screens.
|
||||
class ResponsiveScreen extends StatelessWidget {
|
||||
/// This is the "hero" of the screen. It's more or less square, and will
|
||||
/// be placed in the visual "center" of the screen.
|
||||
final Widget squarishMainArea;
|
||||
|
||||
/// The second-largest area after [squarishMainArea]. It can be narrow
|
||||
/// or wide.
|
||||
final Widget rectangularMenuArea;
|
||||
|
||||
/// An area reserved for some static text close to the top of the screen.
|
||||
final Widget topMessageArea;
|
||||
|
||||
/// How much bigger should the [squarishMainArea] be compared to the other
|
||||
/// elements.
|
||||
final double mainAreaProminence;
|
||||
|
||||
const ResponsiveScreen({
|
||||
required this.squarishMainArea,
|
||||
required this.rectangularMenuArea,
|
||||
this.topMessageArea = const SizedBox.shrink(),
|
||||
this.mainAreaProminence = 0.8,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
// This widget wants to fill the whole screen.
|
||||
final size = constraints.biggest;
|
||||
final padding = EdgeInsets.all(size.shortestSide / 30);
|
||||
|
||||
if (size.height >= size.width) {
|
||||
// "Portrait" / "mobile" mode.
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
SafeArea(
|
||||
bottom: false,
|
||||
child: Padding(
|
||||
padding: padding,
|
||||
child: topMessageArea,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: (mainAreaProminence * 100).round(),
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
bottom: false,
|
||||
minimum: padding,
|
||||
child: squarishMainArea,
|
||||
),
|
||||
),
|
||||
SafeArea(
|
||||
top: false,
|
||||
maintainBottomViewPadding: true,
|
||||
child: Padding(
|
||||
padding: padding,
|
||||
child: rectangularMenuArea,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
// "Landscape" / "tablet" mode.
|
||||
final isLarge = size.width > 900;
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: isLarge ? 7 : 5,
|
||||
child: SafeArea(
|
||||
right: false,
|
||||
maintainBottomViewPadding: true,
|
||||
minimum: padding,
|
||||
child: squarishMainArea,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
children: [
|
||||
SafeArea(
|
||||
bottom: false,
|
||||
left: false,
|
||||
maintainBottomViewPadding: true,
|
||||
child: Padding(
|
||||
padding: padding,
|
||||
child: topMessageArea,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
left: false,
|
||||
maintainBottomViewPadding: true,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Padding(
|
||||
padding: padding,
|
||||
child: rectangularMenuArea,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user