1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-08 13:58:47 +00:00

Flutter 3.29 beta (#2571)

This commit is contained in:
Eric Windmill
2025-02-12 18:08:01 -05:00
committed by GitHub
parent d62c784789
commit 719fd72c38
685 changed files with 76244 additions and 53721 deletions

View File

@@ -31,11 +31,13 @@ void setupWindow() {
setWindowMinSize(const Size(windowWidth, windowHeight));
setWindowMaxSize(const Size(windowWidth, windowHeight));
getCurrentScreen().then((screen) {
setWindowFrame(Rect.fromCenter(
center: screen!.frame.center,
width: windowWidth,
height: windowHeight,
));
setWindowFrame(
Rect.fromCenter(
center: screen!.frame.center,
width: windowWidth,
height: windowHeight,
),
);
});
}
}
@@ -44,18 +46,12 @@ GoRouter router() {
return GoRouter(
initialLocation: '/login',
routes: [
GoRoute(
path: '/login',
builder: (context, state) => const MyLogin(),
),
GoRoute(path: '/login', builder: (context, state) => const MyLogin()),
GoRoute(
path: '/catalog',
builder: (context, state) => const MyCatalog(),
routes: [
GoRoute(
path: 'cart',
builder: (context, state) => const MyCart(),
),
GoRoute(path: 'cart', builder: (context, state) => const MyCart()),
],
),
],

View File

@@ -51,9 +51,9 @@ class Item {
final int price = 42;
Item(this.id, this.name)
// To make the sample app look nicer, each item is given one of the
// Material Design primary colors.
: color = Colors.primaries[id % Colors.primaries.length];
// To make the sample app look nicer, each item is given one of the
// Material Design primary colors.
: color = Colors.primaries[id % Colors.primaries.length];
@override
int get hashCode => id;

View File

@@ -27,7 +27,7 @@ class MyCart extends StatelessWidget {
),
),
const Divider(height: 4, color: Colors.black),
_CartTotal()
_CartTotal(),
],
),
),
@@ -46,19 +46,17 @@ class _CartList extends StatelessWidget {
return ListView.builder(
itemCount: cart.items.length,
itemBuilder: (context, index) => ListTile(
leading: const Icon(Icons.done),
trailing: IconButton(
icon: const Icon(Icons.remove_circle_outline),
onPressed: () {
cart.remove(cart.items[index]);
},
),
title: Text(
cart.items[index].name,
style: itemNameStyle,
),
),
itemBuilder:
(context, index) => ListTile(
leading: const Icon(Icons.done),
trailing: IconButton(
icon: const Icon(Icons.remove_circle_outline),
onPressed: () {
cart.remove(cart.items[index]);
},
),
title: Text(cart.items[index].name, style: itemNameStyle),
),
);
}
}
@@ -66,8 +64,9 @@ class _CartList extends StatelessWidget {
class _CartTotal extends StatelessWidget {
@override
Widget build(BuildContext context) {
var hugeStyle =
Theme.of(context).textTheme.displayLarge!.copyWith(fontSize: 48);
var hugeStyle = Theme.of(
context,
).textTheme.displayLarge!.copyWith(fontSize: 48);
return SizedBox(
height: 200,
@@ -82,13 +81,16 @@ class _CartTotal extends StatelessWidget {
// The important thing is that it will not rebuild
// the rest of the widgets in this build method.
Consumer<CartModel>(
builder: (context, cart, child) =>
Text('\$${cart.totalPrice}', style: hugeStyle)),
builder:
(context, cart, child) =>
Text('\$${cart.totalPrice}', style: hugeStyle),
),
const SizedBox(width: 24),
FilledButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Buying not supported yet.')));
const SnackBar(content: Text('Buying not supported yet.')),
);
},
style: TextButton.styleFrom(foregroundColor: Colors.white),
child: const Text('BUY'),

View File

@@ -20,7 +20,8 @@ class MyCatalog extends StatelessWidget {
const SliverToBoxAdapter(child: SizedBox(height: 12)),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => _MyListItem(index)),
(context, index) => _MyListItem(index),
),
),
],
),
@@ -47,16 +48,17 @@ class _AddButton extends StatelessWidget {
);
return TextButton(
onPressed: isInCart
? null
: () {
// If the item is not in cart, we let the user add it.
// We are using context.read() here because the callback
// is executed whenever the user taps the button. In other
// words, it is executed outside the build method.
var cart = context.read<CartModel>();
cart.add(item);
},
onPressed:
isInCart
? null
: () {
// If the item is not in cart, we let the user add it.
// We are using context.read() here because the callback
// is executed whenever the user taps the button. In other
// words, it is executed outside the build method.
var cart = context.read<CartModel>();
cart.add(item);
},
style: ButtonStyle(
overlayColor: WidgetStateProperty.resolveWith<Color?>((states) {
if (states.contains(WidgetState.pressed)) {
@@ -65,9 +67,10 @@ class _AddButton extends StatelessWidget {
return null; // Defer to the widget's default.
}),
),
child: isInCart
? const Icon(Icons.check, semanticLabel: 'ADDED')
: const Text('ADD'),
child:
isInCart
? const Icon(Icons.check, semanticLabel: 'ADDED')
: const Text('ADD'),
);
}
}
@@ -108,16 +111,9 @@ class _MyListItem extends StatelessWidget {
maxHeight: 48,
child: Row(
children: [
AspectRatio(
aspectRatio: 1,
child: Container(
color: item.color,
),
),
AspectRatio(aspectRatio: 1, child: Container(color: item.color)),
const SizedBox(width: 24),
Expanded(
child: Text(item.name, style: textTheme),
),
Expanded(child: Text(item.name, style: textTheme)),
const SizedBox(width: 24),
_AddButton(item: item),
],

View File

@@ -17,33 +17,22 @@ class MyLogin extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Welcome',
style: Theme.of(context).textTheme.displayLarge,
Text('Welcome', style: Theme.of(context).textTheme.displayLarge),
TextFormField(
decoration: const InputDecoration(hintText: 'Username'),
),
TextFormField(
decoration: const InputDecoration(
hintText: 'Username',
),
),
TextFormField(
decoration: const InputDecoration(
hintText: 'Password',
),
decoration: const InputDecoration(hintText: 'Password'),
obscureText: true,
),
const SizedBox(
height: 24,
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
context.pushReplacement('/catalog');
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.yellow,
),
style: ElevatedButton.styleFrom(backgroundColor: Colors.yellow),
child: const Text('ENTER'),
)
),
],
),
),

View File

@@ -5,7 +5,7 @@ publish_to: none
version: 1.0.0+1
environment:
sdk: ^3.5.0
sdk: ^3.7.0-0
dependencies:
flutter:

View File

@@ -12,22 +12,20 @@ import 'package:provider_shopper/screens/cart.dart';
CartModel? cartModel;
CatalogModel? catalogModel;
Widget createCartScreen() => MultiProvider(
providers: [
Provider(create: (context) => CatalogModel()),
ChangeNotifierProxyProvider<CatalogModel, CartModel>(
create: (context) => CartModel(),
update: (context, catalog, cart) {
catalogModel = catalog;
cartModel = cart;
cart!.catalog = catalogModel!;
return cart;
},
),
],
child: const MaterialApp(
home: MyCart(),
),
);
providers: [
Provider(create: (context) => CatalogModel()),
ChangeNotifierProxyProvider<CatalogModel, CartModel>(
create: (context) => CartModel(),
update: (context, catalog, cart) {
catalogModel = catalog;
cartModel = cart;
cart!.catalog = catalogModel!;
return cart;
},
),
],
child: const MaterialApp(home: MyCart()),
);
void main() {
group('CartScreen widget tests', () {

View File

@@ -10,20 +10,18 @@ import 'package:provider_shopper/models/catalog.dart';
import 'package:provider_shopper/screens/catalog.dart';
Widget createCatalogScreen() => MultiProvider(
providers: [
Provider(create: (context) => CatalogModel()),
ChangeNotifierProxyProvider<CatalogModel, CartModel>(
create: (context) => CartModel(),
update: (context, catalog, cart) {
cart!.catalog = catalog;
return cart;
},
),
],
child: const MaterialApp(
home: MyCatalog(),
),
);
providers: [
Provider(create: (context) => CatalogModel()),
ChangeNotifierProxyProvider<CatalogModel, CartModel>(
create: (context) => CartModel(),
update: (context, catalog, cart) {
cart!.catalog = catalog;
return cart;
},
),
],
child: const MaterialApp(home: MyCatalog()),
);
void main() {
final catalogListItems = CatalogModel.itemNames.sublist(0, 3);
@@ -39,8 +37,9 @@ void main() {
}
});
testWidgets('Testing the ADD buttons and check after clicking',
(tester) async {
testWidgets('Testing the ADD buttons and check after clicking', (
tester,
) async {
await tester.pumpWidget(createCatalogScreen());
// Should find ADD buttons on the screen.

View File

@@ -11,19 +11,21 @@ import 'package:provider_shopper/models/catalog.dart';
void main() {
testWidgets('Login page Widget test', (tester) async {
await tester.pumpWidget(MultiProvider(
providers: [
Provider(create: (context) => CatalogModel()),
ChangeNotifierProxyProvider<CatalogModel, CartModel>(
create: (context) => CartModel(),
update: (context, catalog, cart) {
cart!.catalog = catalog;
return cart;
},
),
],
child: MaterialApp.router(routerConfig: router()),
));
await tester.pumpWidget(
MultiProvider(
providers: [
Provider(create: (context) => CatalogModel()),
ChangeNotifierProxyProvider<CatalogModel, CartModel>(
create: (context) => CartModel(),
update: (context, catalog, cart) {
cart!.catalog = catalog;
return cart;
},
),
],
child: MaterialApp.router(routerConfig: router()),
),
);
// Verifying the behaviour of ENTER button.
await tester.tap(find.text('ENTER'));