`platform_design`: Enforce `use_key_in_widget_constructors` (#927)

pull/929/head
Brett Morgan 3 years ago committed by GitHub
parent ac2bef7d83
commit 0061b0d70d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,5 +17,3 @@ linter:
test_types_in_equals: true
throw_in_finally: true
unnecessary_statements: true
# Tests fail if we enforce `use_key_in_widget_constructors`
use_key_in_widget_constructors: false

@ -11,9 +11,11 @@ import 'settings_tab.dart';
import 'songs_tab.dart';
import 'widgets.dart';
void main() => runApp(MyAdaptingApp());
void main() => runApp(const MyAdaptingApp());
class MyAdaptingApp extends StatelessWidget {
const MyAdaptingApp({Key? key}) : super(key: key);
@override
Widget build(context) {
// Either Material or Cupertino widgets work in either Material or Cupertino
@ -34,6 +36,7 @@ class MyAdaptingApp extends StatelessWidget {
child: Material(child: child),
);
},
// ignore: use_key_in_widget_constructors
home: PlatformAdaptingHomePage(),
);
}
@ -47,6 +50,8 @@ class MyAdaptingApp extends StatelessWidget {
// These differences are also subjective and have more than one 'right' answer
// depending on the app and content.
class PlatformAdaptingHomePage extends StatefulWidget {
const PlatformAdaptingHomePage({Key? key}) : super(key: key);
@override
_PlatformAdaptingHomePageState createState() =>
_PlatformAdaptingHomePageState();
@ -107,12 +112,12 @@ class _PlatformAdaptingHomePageState extends State<PlatformAdaptingHomePage> {
case 1:
return CupertinoTabView(
defaultTitle: NewsTab.title,
builder: (context) => NewsTab(),
builder: (context) => const NewsTab(),
);
case 2:
return CupertinoTabView(
defaultTitle: ProfileTab.title,
builder: (context) => ProfileTab(),
builder: (context) => const ProfileTab(),
);
default:
assert(false, 'Unexpected tab');
@ -161,8 +166,8 @@ class _AndroidDrawer extends StatelessWidget {
title: const Text(NewsTab.title),
onTap: () {
Navigator.pop(context);
Navigator.push<void>(
context, MaterialPageRoute(builder: (context) => NewsTab()));
Navigator.push<void>(context,
MaterialPageRoute(builder: (context) => const NewsTab()));
},
),
ListTile(
@ -171,7 +176,7 @@ class _AndroidDrawer extends StatelessWidget {
onTap: () {
Navigator.pop(context);
Navigator.push<void>(context,
MaterialPageRoute(builder: (context) => ProfileTab()));
MaterialPageRoute(builder: (context) => const ProfileTab()));
},
),
// Long drawer contents are often segmented.
@ -185,7 +190,7 @@ class _AndroidDrawer extends StatelessWidget {
onTap: () {
Navigator.pop(context);
Navigator.push<void>(context,
MaterialPageRoute(builder: (context) => SettingsTab()));
MaterialPageRoute(builder: (context) => const SettingsTab()));
},
),
],

@ -15,6 +15,8 @@ class NewsTab extends StatefulWidget {
static const androidIcon = Icon(Icons.library_books);
static const iosIcon = Icon(CupertinoIcons.news);
const NewsTab({Key? key}) : super(key: key);
@override
_NewsTabState createState() => _NewsTabState();
}

@ -13,6 +13,8 @@ class ProfileTab extends StatelessWidget {
static const androidIcon = Icon(Icons.person);
static const iosIcon = Icon(CupertinoIcons.profile_circled);
const ProfileTab({Key? key}) : super(key: key);
Widget _buildBody(BuildContext context) {
return SafeArea(
child: Padding(
@ -55,7 +57,7 @@ class ProfileTab extends StatelessWidget {
Expanded(
child: Container(),
),
LogOutButton(),
const LogOutButton(),
],
),
),
@ -89,7 +91,7 @@ class ProfileTab extends StatelessWidget {
CupertinoPageRoute(
title: SettingsTab.title,
fullscreenDialog: true,
builder: (context) => SettingsTab(),
builder: (context) => const SettingsTab(),
),
);
},
@ -113,7 +115,8 @@ class PreferenceCard extends StatelessWidget {
required this.header,
required this.content,
required this.preferenceChoices,
});
Key? key,
}) : super(key: key);
final String header;
final String content;
@ -171,6 +174,8 @@ class LogOutButton extends StatelessWidget {
static const _logoutMessage = Text(
"You can't actually log out! This is just a demo of how alerts work.");
const LogOutButton({Key? key}) : super(key: key);
// ===========================================================================
// Non-shared code below because this tab shows different interfaces. On
// Android, it's showing an alert dialog with 2 buttons and on iOS,

@ -12,6 +12,8 @@ class SettingsTab extends StatefulWidget {
static const androidIcon = Icon(Icons.settings);
static const iosIcon = Icon(CupertinoIcons.gear);
const SettingsTab({Key? key}) : super(key: key);
@override
_SettingsTabState createState() => _SettingsTabState();
}

@ -16,7 +16,8 @@ class SongDetailTab extends StatelessWidget {
required this.id,
required this.song,
required this.color,
});
Key? key,
}) : super(key: key);
final int id;
final String song;
@ -71,7 +72,7 @@ class SongDetailTab extends StatelessWidget {
);
}
// Just a bunch of boxes that simulates loading song choices.
return SongPlaceholderTile();
return const SongPlaceholderTile();
},
),
),

@ -41,7 +41,8 @@ class PressableCard extends StatefulWidget {
required this.color,
required this.flattenAnimation,
this.child,
});
Key? key,
}) : super(key: key);
final VoidCallback? onPressed;
final Color color;
@ -140,7 +141,8 @@ class HeroAnimatingSongCard extends StatelessWidget {
required this.color,
required this.heroAnimation,
this.onPressed,
});
Key? key,
}) : super(key: key);
final String song;
final Color color;
@ -218,6 +220,8 @@ class HeroAnimatingSongCard extends StatelessWidget {
/// This is an example of a custom widget that an app developer might create for
/// use on both iOS and Android as part of their brand's unique design.
class SongPlaceholderTile extends StatelessWidget {
const SongPlaceholderTile({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(

@ -11,7 +11,7 @@ import 'package:platform_design/main.dart';
void main() {
testWidgets('Can change platform correctly', (tester) async {
await tester.pumpWidget(MyAdaptingApp());
await tester.pumpWidget(const MyAdaptingApp());
// The test should be able to find the drawer button.
expect(find.byIcon(Icons.menu), findsOneWidget);
@ -19,7 +19,7 @@ void main() {
expect(find.byIcon(Icons.refresh), findsOneWidget);
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
await tester.pumpWidget(MyAdaptingApp());
await tester.pumpWidget(const MyAdaptingApp());
// There should now be a large title style nav bar.
expect(find.byType(CupertinoSliverNavigationBar), findsOneWidget);

Loading…
Cancel
Save