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:
@@ -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()),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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),
|
||||
],
|
||||
|
||||
@@ -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'),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -5,7 +5,7 @@ publish_to: none
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
@@ -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', () {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'));
|
||||
|
||||
Reference in New Issue
Block a user