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

@@ -30,11 +30,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,
),
);
});
}
}
@@ -43,10 +45,11 @@ final demos = [
Demo(
name: 'Sign in with HTTP',
route: 'signin_http',
builder: (context) => SignInHttpDemo(
// This sample uses a mock HTTP client.
httpClient: mockClient,
),
builder:
(context) => SignInHttpDemo(
// This sample uses a mock HTTP client.
httpClient: mockClient,
),
),
Demo(
name: 'Autofill',
@@ -88,9 +91,7 @@ class FormApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Form Samples',
theme: ThemeData(
colorSchemeSeed: Colors.teal,
),
theme: ThemeData(colorSchemeSeed: Colors.teal),
routerConfig: router,
);
}
@@ -102,12 +103,8 @@ class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Form Samples'),
),
body: ListView(
children: [...demos.map((d) => DemoTile(demo: d))],
),
appBar: AppBar(title: const Text('Form Samples')),
body: ListView(children: [...demos.map((d) => DemoTile(demo: d))]),
);
}
}

View File

@@ -19,9 +19,7 @@ class _AutofillDemoState extends State<AutofillDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Autofill'),
),
appBar: AppBar(title: const Text('Autofill')),
body: Form(
key: _formKey,
child: Scrollbar(
@@ -101,14 +99,7 @@ class _AutofillDemoState extends State<AutofillDemo> {
),
autofillHints: [AutofillHints.countryCode],
),
].expand(
(widget) => [
widget,
const SizedBox(
height: 24,
)
],
)
].expand((widget) => [widget, const SizedBox(height: 24)]),
],
),
),

View File

@@ -24,9 +24,7 @@ class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Form widgets'),
),
appBar: AppBar(title: const Text('Form widgets')),
body: Form(
key: _formKey,
child: Scrollbar(
@@ -89,8 +87,9 @@ class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
),
Text(
intl.NumberFormat.currency(
symbol: "\$", decimalDigits: 0)
.format(maxValue),
symbol: "\$",
decimalDigits: 0,
).format(maxValue),
style: Theme.of(context).textTheme.titleMedium,
),
Slider(
@@ -118,16 +117,20 @@ class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
});
},
),
Text('Brushed Teeth',
style: Theme.of(context).textTheme.titleMedium),
Text(
'Brushed Teeth',
style: Theme.of(context).textTheme.titleMedium,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Enable feature',
style: Theme.of(context).textTheme.bodyLarge),
Text(
'Enable feature',
style: Theme.of(context).textTheme.bodyLarge,
),
Switch(
value: enableFeature,
onChanged: (enabled) {
@@ -139,13 +142,8 @@ class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
],
),
].expand(
(widget) => [
widget,
const SizedBox(
height: 24,
)
],
)
(widget) => [widget, const SizedBox(height: 24)],
),
],
),
),
@@ -162,10 +160,7 @@ class _FormDatePicker extends StatefulWidget {
final DateTime date;
final ValueChanged<DateTime> onChanged;
const _FormDatePicker({
required this.date,
required this.onChanged,
});
const _FormDatePicker({required this.date, required this.onChanged});
@override
State<_FormDatePicker> createState() => _FormDatePickerState();
@@ -182,10 +177,7 @@ class _FormDatePickerState extends State<_FormDatePicker> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'Date',
style: Theme.of(context).textTheme.bodyLarge,
),
Text('Date', style: Theme.of(context).textTheme.bodyLarge),
Text(
intl.DateFormat.yMd().format(widget.date),
style: Theme.of(context).textTheme.titleMedium,
@@ -209,7 +201,7 @@ class _FormDatePickerState extends State<_FormDatePicker> {
widget.onChanged(newDate);
},
)
),
],
);
}

View File

@@ -8,7 +8,8 @@ final http.Client mockClient = MockClient(_mockHandler);
Future<http.Response> _mockHandler(http.Request request) async {
var decodedJson = Map<String, dynamic>.from(
json.decode(request.body) as Map<String, dynamic>);
json.decode(request.body) as Map<String, dynamic>,
);
if (decodedJson['email'] == 'root' && decodedJson['password'] == 'password') {
return http.Response('', 200);

View File

@@ -15,10 +15,7 @@ class FormData {
String? email;
String? password;
FormData({
this.email,
this.password,
});
FormData({this.email, this.password});
factory FormData.fromJson(Map<String, dynamic> json) =>
_$FormDataFromJson(json);
@@ -29,10 +26,7 @@ class FormData {
class SignInHttpDemo extends StatefulWidget {
final http.Client? httpClient;
const SignInHttpDemo({
this.httpClient,
super.key,
});
const SignInHttpDemo({this.httpClient, super.key});
@override
State<SignInHttpDemo> createState() => _SignInHttpDemoState();
@@ -44,9 +38,7 @@ class _SignInHttpDemoState extends State<SignInHttpDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sign in Form'),
),
appBar: AppBar(title: const Text('Sign in Form')),
body: Form(
child: Scrollbar(
child: SingleChildScrollView(
@@ -81,25 +73,19 @@ class _SignInHttpDemoState extends State<SignInHttpDemo> {
onPressed: () async {
// Use a JSON encoded string to send
var result = await widget.httpClient!.post(
Uri.parse('https://example.com/signin'),
body: json.encode(formData.toJson()),
headers: {'content-type': 'application/json'});
Uri.parse('https://example.com/signin'),
body: json.encode(formData.toJson()),
headers: {'content-type': 'application/json'},
);
_showDialog(switch (result.statusCode) {
200 => 'Successfully signed in.',
401 => 'Unable to sign in.',
_ => 'Something went wrong. Please try again.'
_ => 'Something went wrong. Please try again.',
});
},
),
].expand(
(widget) => [
widget,
const SizedBox(
height: 24,
)
],
)
].expand((widget) => [widget, const SizedBox(height: 24)]),
],
),
),
@@ -111,15 +97,16 @@ class _SignInHttpDemoState extends State<SignInHttpDemo> {
void _showDialog(String message) {
showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: Text(message),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () => Navigator.of(context).pop(),
builder:
(context) => AlertDialog(
title: Text(message),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
],
),
);
}
}

View File

@@ -14,6 +14,6 @@ FormData _$FormDataFromJson(Map<String, dynamic> json) {
}
Map<String, dynamic> _$FormDataToJson(FormData instance) => <String, dynamic>{
'email': instance.email,
'password': instance.password,
};
'email': instance.email,
'password': instance.password,
};

View File

@@ -38,18 +38,19 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Your story'),
content: Text('The $adjective developer saw a $noun'),
actions: [
TextButton(
child: const Text('Done'),
onPressed: () {
Navigator.of(context).pop();
},
builder:
(context) => AlertDialog(
title: const Text('Your story'),
content: Text('The $adjective developer saw a $noun'),
actions: [
TextButton(
child: const Text('Done'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
],
),
);
},
),
@@ -85,9 +86,7 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
adjective = value;
},
),
const SizedBox(
height: 24,
),
const SizedBox(height: 24),
// A text field that validates that the text is a noun.
TextFormField(
validator: (value) {
@@ -108,9 +107,7 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
noun = value;
},
),
const SizedBox(
height: 24,
),
const SizedBox(height: 24),
// A custom form field that requires the user to check a
// checkbox.
FormField<bool>(
@@ -148,11 +145,11 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
if (!formFieldState.isValid)
Text(
formFieldState.errorText ?? "",
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: Theme.of(context).colorScheme.error),
style: Theme.of(
context,
).textTheme.bodySmall!.copyWith(
color: Theme.of(context).colorScheme.error,
),
),
],
);

View File

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

View File

@@ -23,11 +23,9 @@ void main() {
}
Future<void> _signIn(WidgetTester tester, String email, String password) async {
await tester.pumpWidget(MaterialApp(
home: SignInHttpDemo(
httpClient: mockClient,
),
));
await tester.pumpWidget(
MaterialApp(home: SignInHttpDemo(httpClient: mockClient)),
);
var textFormField = find.byType(TextFormField);
expect(textFormField, findsNWidgets(2));