mirror of
https://github.com/flutter/samples.git
synced 2026-06-13 01:39:16 +00:00
Flutter 3.29 beta (#2571)
This commit is contained in:
@@ -19,22 +19,20 @@ class AuthorDetailsScreen extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(author.name),
|
||||
),
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: BookList(
|
||||
books: author.books,
|
||||
onTap: (book) {
|
||||
onBookTapped(book);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
appBar: AppBar(title: Text(author.name)),
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: BookList(
|
||||
books: author.books,
|
||||
onTap: (book) {
|
||||
onBookTapped(book);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,20 +12,11 @@ class AuthorsScreen extends StatelessWidget {
|
||||
final String title;
|
||||
final ValueChanged<Author> onTap;
|
||||
|
||||
const AuthorsScreen({
|
||||
required this.onTap,
|
||||
this.title = 'Authors',
|
||||
super.key,
|
||||
});
|
||||
const AuthorsScreen({required this.onTap, this.title = 'Authors', super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(title),
|
||||
),
|
||||
body: AuthorList(
|
||||
authors: libraryInstance.allAuthors,
|
||||
onTap: onTap,
|
||||
),
|
||||
);
|
||||
appBar: AppBar(title: Text(title)),
|
||||
body: AuthorList(authors: libraryInstance.allAuthors, onTap: onTap),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,24 +12,15 @@ import 'author_details.dart';
|
||||
class BookDetailsScreen extends StatelessWidget {
|
||||
final Book? book;
|
||||
|
||||
const BookDetailsScreen({
|
||||
super.key,
|
||||
this.book,
|
||||
});
|
||||
const BookDetailsScreen({super.key, this.book});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (book == null) {
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: Text('No book found.'),
|
||||
),
|
||||
);
|
||||
return const Scaffold(body: Center(child: Text('No book found.')));
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(book!.title),
|
||||
),
|
||||
appBar: AppBar(title: Text(book!.title)),
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -46,22 +37,26 @@ class BookDetailsScreen extends StatelessWidget {
|
||||
onPressed: () {
|
||||
Navigator.of(context).push<void>(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => AuthorDetailsScreen(
|
||||
author: book!.author,
|
||||
onBookTapped: (book) {
|
||||
GoRouter.of(context).go('/books/all/book/${book.id}');
|
||||
},
|
||||
),
|
||||
builder:
|
||||
(context) => AuthorDetailsScreen(
|
||||
author: book!.author,
|
||||
onBookTapped: (book) {
|
||||
GoRouter.of(
|
||||
context,
|
||||
).go('/books/all/book/${book.id}');
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Link(
|
||||
uri: Uri.parse('/authors/author/${book!.author.id}'),
|
||||
builder: (context, followLink) => TextButton(
|
||||
onPressed: followLink,
|
||||
child: const Text('View author (Link)'),
|
||||
),
|
||||
builder:
|
||||
(context, followLink) => TextButton(
|
||||
onPressed: followLink,
|
||||
child: const Text('View author (Link)'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -46,18 +46,9 @@ class _BooksScreenState extends State<BooksScreen>
|
||||
bottom: TabBar(
|
||||
controller: _tabController,
|
||||
tabs: const [
|
||||
Tab(
|
||||
text: 'Popular',
|
||||
icon: Icon(Icons.people),
|
||||
),
|
||||
Tab(
|
||||
text: 'New',
|
||||
icon: Icon(Icons.new_releases),
|
||||
),
|
||||
Tab(
|
||||
text: 'All',
|
||||
icon: Icon(Icons.list),
|
||||
),
|
||||
Tab(text: 'Popular', icon: Icon(Icons.people)),
|
||||
Tab(text: 'New', icon: Icon(Icons.new_releases)),
|
||||
Tab(text: 'All', icon: Icon(Icons.list)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -30,18 +30,9 @@ class BookstoreScaffold extends StatelessWidget {
|
||||
if (idx == 2) goRouter.go('/settings');
|
||||
},
|
||||
destinations: const [
|
||||
AdaptiveScaffoldDestination(
|
||||
title: 'Books',
|
||||
icon: Icons.book,
|
||||
),
|
||||
AdaptiveScaffoldDestination(
|
||||
title: 'Authors',
|
||||
icon: Icons.person,
|
||||
),
|
||||
AdaptiveScaffoldDestination(
|
||||
title: 'Settings',
|
||||
icon: Icons.settings,
|
||||
),
|
||||
AdaptiveScaffoldDestination(title: 'Books', icon: Icons.book),
|
||||
AdaptiveScaffoldDestination(title: 'Authors', icon: Icons.person),
|
||||
AdaptiveScaffoldDestination(title: 'Settings', icon: Icons.settings),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -18,81 +18,79 @@ class SettingsScreen extends StatefulWidget {
|
||||
class _SettingsScreenState extends State<SettingsScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 400),
|
||||
child: const Card(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 18, horizontal: 12),
|
||||
child: SettingsContent(),
|
||||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 400),
|
||||
child: const Card(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 18, horizontal: 12),
|
||||
child: SettingsContent(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class SettingsContent extends StatelessWidget {
|
||||
const SettingsContent({
|
||||
super.key,
|
||||
});
|
||||
const SettingsContent({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
children: [
|
||||
...[
|
||||
Text(
|
||||
'Settings',
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () {
|
||||
BookstoreAuth.of(context).signOut();
|
||||
},
|
||||
child: const Text('Sign out'),
|
||||
),
|
||||
const Text('Example using the Link widget:'),
|
||||
Link(
|
||||
uri: Uri.parse('/books/all/book/0'),
|
||||
builder: (context, followLink) => TextButton(
|
||||
children: [
|
||||
...[
|
||||
Text('Settings', style: Theme.of(context).textTheme.headlineMedium),
|
||||
FilledButton(
|
||||
onPressed: () {
|
||||
BookstoreAuth.of(context).signOut();
|
||||
},
|
||||
child: const Text('Sign out'),
|
||||
),
|
||||
const Text('Example using the Link widget:'),
|
||||
Link(
|
||||
uri: Uri.parse('/books/all/book/0'),
|
||||
builder:
|
||||
(context, followLink) => TextButton(
|
||||
onPressed: followLink,
|
||||
child: const Text('/books/all/book/0'),
|
||||
),
|
||||
),
|
||||
const Text('Example using GoRouter.of(context).go():'),
|
||||
TextButton(
|
||||
child: const Text('/books/all/book/0'),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).go('/books/all/book/0');
|
||||
},
|
||||
),
|
||||
].map((w) => Padding(padding: const EdgeInsets.all(8), child: w)),
|
||||
const Text('Displays a dialog on the root Navigator:'),
|
||||
TextButton(
|
||||
onPressed: () => showDialog<String>(
|
||||
),
|
||||
const Text('Example using GoRouter.of(context).go():'),
|
||||
TextButton(
|
||||
child: const Text('/books/all/book/0'),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).go('/books/all/book/0');
|
||||
},
|
||||
),
|
||||
].map((w) => Padding(padding: const EdgeInsets.all(8), child: w)),
|
||||
const Text('Displays a dialog on the root Navigator:'),
|
||||
TextButton(
|
||||
onPressed:
|
||||
() => showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Alert!'),
|
||||
content: const Text('The alert description goes here.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||
child: const Text('Cancel'),
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: const Text('Alert!'),
|
||||
content: const Text('The alert description goes here.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: const Text('Show Dialog'),
|
||||
)
|
||||
],
|
||||
);
|
||||
child: const Text('Show Dialog'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ class Credentials {
|
||||
class SignInScreen extends StatefulWidget {
|
||||
final ValueChanged<Credentials> onSignIn;
|
||||
|
||||
const SignInScreen({
|
||||
required this.onSignIn,
|
||||
super.key,
|
||||
});
|
||||
const SignInScreen({required this.onSignIn, super.key});
|
||||
|
||||
@override
|
||||
State<SignInScreen> createState() => _SignInScreenState();
|
||||
@@ -29,41 +26,46 @@ class _SignInScreenState extends State<SignInScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
body: Center(
|
||||
child: Card(
|
||||
child: Container(
|
||||
constraints: BoxConstraints.loose(const Size(600, 600)),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('Sign in',
|
||||
style: Theme.of(context).textTheme.headlineMedium),
|
||||
TextField(
|
||||
decoration: const InputDecoration(labelText: 'Username'),
|
||||
controller: _usernameController,
|
||||
),
|
||||
TextField(
|
||||
decoration: const InputDecoration(labelText: 'Password'),
|
||||
obscureText: true,
|
||||
controller: _passwordController,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: TextButton(
|
||||
onPressed: () async {
|
||||
widget.onSignIn(Credentials(
|
||||
_usernameController.value.text,
|
||||
_passwordController.value.text));
|
||||
},
|
||||
child: const Text('Sign in'),
|
||||
),
|
||||
),
|
||||
],
|
||||
body: Center(
|
||||
child: Card(
|
||||
child: Container(
|
||||
constraints: BoxConstraints.loose(const Size(600, 600)),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'Sign in',
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
decoration: const InputDecoration(labelText: 'Username'),
|
||||
controller: _usernameController,
|
||||
),
|
||||
TextField(
|
||||
decoration: const InputDecoration(labelText: 'Password'),
|
||||
obscureText: true,
|
||||
controller: _passwordController,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: TextButton(
|
||||
onPressed: () async {
|
||||
widget.onSignIn(
|
||||
Credentials(
|
||||
_usernameController.value.text,
|
||||
_passwordController.value.text,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('Sign in'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user