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:
@@ -62,8 +62,12 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
|
||||
Color randomLightColor() {
|
||||
_random ??= Random(cellNumber);
|
||||
|
||||
return Color.fromARGB(255, _random!.nextInt(50) + 205,
|
||||
_random!.nextInt(50) + 205, _random!.nextInt(50) + 205);
|
||||
return Color.fromARGB(
|
||||
255,
|
||||
_random!.nextInt(50) + 205,
|
||||
_random!.nextInt(50) + 205,
|
||||
_random!.nextInt(50) + 205,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -108,20 +112,25 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
|
||||
child: StreamBuilder<AccelerometerEvent>(
|
||||
// Don't continuously rebuild for nothing when the
|
||||
// cell isn't visible.
|
||||
stream: appLifecycleState == AppLifecycleState.resumed
|
||||
? accelerometerEventStream()
|
||||
: Stream.value(defaultPosition),
|
||||
stream:
|
||||
appLifecycleState == AppLifecycleState.resumed
|
||||
? accelerometerEventStream()
|
||||
: Stream.value(defaultPosition),
|
||||
initialData: defaultPosition,
|
||||
builder: (context, snapshot) {
|
||||
return Transform(
|
||||
// Figure out the phone's orientation relative
|
||||
// to gravity's direction. Ignore the z vector.
|
||||
transform: Matrix4.rotationX(
|
||||
snapshot.data!.y / gravity * pi / 2)
|
||||
..multiply(Matrix4.rotationY(
|
||||
snapshot.data!.x / gravity * pi / 2)),
|
||||
alignment: Alignment.center,
|
||||
child: const FlutterLogo(size: 72));
|
||||
// Figure out the phone's orientation relative
|
||||
// to gravity's direction. Ignore the z vector.
|
||||
transform: Matrix4.rotationX(
|
||||
snapshot.data!.y / gravity * pi / 2,
|
||||
)..multiply(
|
||||
Matrix4.rotationY(
|
||||
snapshot.data!.x / gravity * pi / 2,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: const FlutterLogo(size: 72),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -17,12 +17,7 @@ void main() {
|
||||
|
||||
final model = CounterModel();
|
||||
|
||||
runApp(
|
||||
ChangeNotifierProvider.value(
|
||||
value: model,
|
||||
child: const MyApp(),
|
||||
),
|
||||
);
|
||||
runApp(ChangeNotifierProvider.value(value: model, child: const MyApp()));
|
||||
}
|
||||
|
||||
/// This is on alternate entrypoint for this module to display Flutter UI in
|
||||
@@ -76,9 +71,7 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Module Title',
|
||||
theme: ThemeData(
|
||||
colorSchemeSeed: Colors.blue,
|
||||
),
|
||||
theme: ThemeData(colorSchemeSeed: Colors.blue),
|
||||
routes: {
|
||||
'/': (context) => const FullScreenView(),
|
||||
'/mini': (context) => const Contents(),
|
||||
@@ -95,9 +88,7 @@ class FullScreenView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Full-screen Flutter with plugin'),
|
||||
),
|
||||
appBar: AppBar(title: const Text('Full-screen Flutter with plugin')),
|
||||
body: const Contents(showExit: true),
|
||||
);
|
||||
}
|
||||
@@ -131,10 +122,7 @@ class Contents extends StatelessWidget {
|
||||
const Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: .25,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.cover,
|
||||
child: FlutterLogo(),
|
||||
),
|
||||
child: FittedBox(fit: BoxFit.cover, child: FlutterLogo()),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
|
||||
@@ -4,7 +4,7 @@ description: An example Flutter module that uses a plugin.
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
@@ -13,9 +13,7 @@ class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(
|
||||
primaryColor: const Color(0xff6200ee),
|
||||
),
|
||||
theme: ThemeData(primaryColor: const Color(0xff6200ee)),
|
||||
home: const BookDetail(),
|
||||
);
|
||||
}
|
||||
@@ -70,30 +68,33 @@ class _BookDetailState extends State<BookDetail> {
|
||||
// calls from the platform.
|
||||
// TODO(gaaclarke): make the setup method an instance method so it's
|
||||
// injectable https://github.com/flutter/flutter/issues/59119.
|
||||
FlutterBookApi.setup(FlutterBookApiHandler(
|
||||
FlutterBookApi.setup(
|
||||
FlutterBookApiHandler(
|
||||
// The `FlutterBookApi` just has one method. Just give a closure for that
|
||||
// method to the handler class.
|
||||
(book) {
|
||||
setState(() {
|
||||
// This book model is what we're going to return to Kotlin eventually.
|
||||
// Keep it bound to the UI.
|
||||
this.book = book;
|
||||
titleTextController.text = book.title ?? '';
|
||||
titleTextController.addListener(() {
|
||||
this.book!.title = titleTextController.text;
|
||||
});
|
||||
// Subtitle could be null.
|
||||
// TODO(gaaclarke): https://github.com/flutter/flutter/issues/59118.
|
||||
subtitleTextController.text = book.subtitle ?? '';
|
||||
subtitleTextController.addListener(() {
|
||||
this.book!.subtitle = subtitleTextController.text;
|
||||
});
|
||||
authorTextController.text = book.author ?? '';
|
||||
authorTextController.addListener(() {
|
||||
this.book!.author = authorTextController.text;
|
||||
});
|
||||
});
|
||||
}));
|
||||
setState(() {
|
||||
// This book model is what we're going to return to Kotlin eventually.
|
||||
// Keep it bound to the UI.
|
||||
this.book = book;
|
||||
titleTextController.text = book.title ?? '';
|
||||
titleTextController.addListener(() {
|
||||
this.book!.title = titleTextController.text;
|
||||
});
|
||||
// Subtitle could be null.
|
||||
// TODO(gaaclarke): https://github.com/flutter/flutter/issues/59118.
|
||||
subtitleTextController.text = book.subtitle ?? '';
|
||||
subtitleTextController.addListener(() {
|
||||
this.book!.subtitle = subtitleTextController.text;
|
||||
});
|
||||
authorTextController.text = book.author ?? '';
|
||||
authorTextController.addListener(() {
|
||||
this.book!.author = authorTextController.text;
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Not overriding didUpdateWidget because the Android program can't change
|
||||
@@ -124,26 +125,28 @@ class _BookDetailState extends State<BookDetail> {
|
||||
IconButton(
|
||||
icon: const Icon(Icons.check),
|
||||
// Pressing save sends the updated book to the platform.
|
||||
onPressed: book != null
|
||||
? () {
|
||||
hostApi.finishEditingBook(book!);
|
||||
clear();
|
||||
}
|
||||
: null,
|
||||
onPressed:
|
||||
book != null
|
||||
? () {
|
||||
hostApi.finishEditingBook(book!);
|
||||
clear();
|
||||
}
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: book == null
|
||||
// Draw a spinner until the platform gives us the book to show details
|
||||
// for.
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: BookForm(
|
||||
book: book!,
|
||||
focusNode: textFocusNode,
|
||||
authorTextController: authorTextController,
|
||||
subtitleTextController: subtitleTextController,
|
||||
titleTextController: titleTextController,
|
||||
),
|
||||
body:
|
||||
book == null
|
||||
// Draw a spinner until the platform gives us the book to show details
|
||||
// for.
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: BookForm(
|
||||
book: book!,
|
||||
focusNode: textFocusNode,
|
||||
authorTextController: authorTextController,
|
||||
subtitleTextController: subtitleTextController,
|
||||
titleTextController: titleTextController,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -207,15 +210,14 @@ class BookForm extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'${book.pageCount} pages ~ published ${book.publishDate}'),
|
||||
'${book.pageCount} pages ~ published ${book.publishDate}',
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const SizedBox(height: 32),
|
||||
if (book.thumbnail?.url != null) ...[
|
||||
Center(
|
||||
child: Image.network(book.thumbnail!.url!),
|
||||
),
|
||||
Center(child: Image.network(book.thumbnail!.url!)),
|
||||
const SizedBox(height: 32),
|
||||
],
|
||||
if (book.summary != null) ...[
|
||||
@@ -234,7 +236,7 @@ class BookForm extends StatelessWidget {
|
||||
book.summary ?? '',
|
||||
style: TextStyle(color: Colors.grey.shade600, height: 1.24),
|
||||
),
|
||||
]
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ description: A Flutter module using the Pigeon package to demonstrate
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
@@ -12,9 +12,7 @@ void main() {
|
||||
MockHostBookApi mockHostApi = MockHostBookApi();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: BookDetail(hostApi: mockHostApi),
|
||||
),
|
||||
MaterialApp(home: BookDetail(hostApi: mockHostApi)),
|
||||
);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.clear));
|
||||
@@ -26,9 +24,7 @@ void main() {
|
||||
MockHostBookApi mockHostApi = MockHostBookApi();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: BookDetail(book: Book(), hostApi: mockHostApi),
|
||||
),
|
||||
MaterialApp(home: BookDetail(book: Book(), hostApi: mockHostApi)),
|
||||
);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.check));
|
||||
|
||||
@@ -14,12 +14,7 @@ void main() {
|
||||
|
||||
final model = CounterModel();
|
||||
|
||||
runApp(
|
||||
ChangeNotifierProvider.value(
|
||||
value: model,
|
||||
child: const MyApp(),
|
||||
),
|
||||
);
|
||||
runApp(ChangeNotifierProvider.value(value: model, child: const MyApp()));
|
||||
}
|
||||
|
||||
/// A simple model that uses a [MethodChannel] as the source of truth for the
|
||||
@@ -81,9 +76,7 @@ class FullScreenView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Full-screen Flutter'),
|
||||
),
|
||||
appBar: AppBar(title: const Text('Full-screen Flutter')),
|
||||
body: const Contents(showExit: true),
|
||||
);
|
||||
}
|
||||
@@ -116,10 +109,7 @@ class Contents extends StatelessWidget {
|
||||
const Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: .25,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.cover,
|
||||
child: FlutterLogo(),
|
||||
),
|
||||
child: FittedBox(fit: BoxFit.cover, child: FlutterLogo()),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
|
||||
@@ -4,7 +4,7 @@ description: An example Flutter module.
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
@@ -72,24 +72,17 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.title),
|
||||
),
|
||||
appBar: AppBar(title: Text(widget.title)),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'You have pushed the button this many times:',
|
||||
),
|
||||
const Text('You have pushed the button this many times:'),
|
||||
Text(
|
||||
'$_counter',
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: _incrementCounter,
|
||||
child: const Text('Add'),
|
||||
),
|
||||
TextButton(onPressed: _incrementCounter, child: const Text('Add')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
_channel.invokeMethod<void>("next", _counter);
|
||||
|
||||
@@ -4,7 +4,7 @@ description: A module that is embedded in the multiple_flutters_ios and multiple
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
@@ -62,8 +62,12 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
|
||||
Color randomLightColor() {
|
||||
_random ??= Random(cellNumber);
|
||||
|
||||
return Color.fromARGB(255, _random!.nextInt(50) + 205,
|
||||
_random!.nextInt(50) + 205, _random!.nextInt(50) + 205);
|
||||
return Color.fromARGB(
|
||||
255,
|
||||
_random!.nextInt(50) + 205,
|
||||
_random!.nextInt(50) + 205,
|
||||
_random!.nextInt(50) + 205,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -108,9 +112,10 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
|
||||
child: StreamBuilder<AccelerometerEvent>(
|
||||
// Don't continuously rebuild for nothing when the
|
||||
// cell isn't visible.
|
||||
stream: appLifecycleState == AppLifecycleState.resumed
|
||||
? accelerometerEventStream()
|
||||
: Stream.value(defaultPosition),
|
||||
stream:
|
||||
appLifecycleState == AppLifecycleState.resumed
|
||||
? accelerometerEventStream()
|
||||
: Stream.value(defaultPosition),
|
||||
initialData: defaultPosition,
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.data;
|
||||
@@ -123,7 +128,8 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
|
||||
transform: Matrix4.rotationX(
|
||||
data.y / gravity * pi / 2,
|
||||
)..multiply(
|
||||
Matrix4.rotationY(data.x / gravity * pi / 2)),
|
||||
Matrix4.rotationY(data.x / gravity * pi / 2),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: const FlutterLogo(size: 72),
|
||||
);
|
||||
|
||||
@@ -17,12 +17,7 @@ void main() {
|
||||
|
||||
final model = CounterModel();
|
||||
|
||||
runApp(
|
||||
ChangeNotifierProvider.value(
|
||||
value: model,
|
||||
child: const MyApp(),
|
||||
),
|
||||
);
|
||||
runApp(ChangeNotifierProvider.value(value: model, child: const MyApp()));
|
||||
}
|
||||
|
||||
/// This is on alternate entrypoint for this module to display Flutter UI in
|
||||
@@ -92,9 +87,7 @@ class FullScreenView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Full-screen Flutter with plugin'),
|
||||
),
|
||||
appBar: AppBar(title: const Text('Full-screen Flutter with plugin')),
|
||||
body: const Contents(showExit: true),
|
||||
);
|
||||
}
|
||||
@@ -128,10 +121,7 @@ class Contents extends StatelessWidget {
|
||||
const Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: .25,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.cover,
|
||||
child: FlutterLogo(),
|
||||
),
|
||||
child: FittedBox(fit: BoxFit.cover, child: FlutterLogo()),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
|
||||
@@ -4,7 +4,7 @@ description: An example Flutter module that uses a plugin.
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
@@ -14,12 +14,7 @@ void main() {
|
||||
|
||||
final model = CounterModel();
|
||||
|
||||
runApp(
|
||||
ChangeNotifierProvider.value(
|
||||
value: model,
|
||||
child: const MyApp(),
|
||||
),
|
||||
);
|
||||
runApp(ChangeNotifierProvider.value(value: model, child: const MyApp()));
|
||||
}
|
||||
|
||||
/// A simple model that uses a [MethodChannel] as the source of truth for the
|
||||
@@ -81,9 +76,7 @@ class FullScreenView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Full-screen Flutter'),
|
||||
),
|
||||
appBar: AppBar(title: const Text('Full-screen Flutter')),
|
||||
body: const Contents(showExit: true),
|
||||
);
|
||||
}
|
||||
@@ -116,10 +109,7 @@ class Contents extends StatelessWidget {
|
||||
const Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: .25,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.cover,
|
||||
child: FlutterLogo(),
|
||||
),
|
||||
child: FittedBox(fit: BoxFit.cover, child: FlutterLogo()),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
|
||||
@@ -4,7 +4,7 @@ description: An example Flutter module.
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.5.0
|
||||
sdk: ^3.7.0-0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
||||
Reference in New Issue
Block a user